برنامه نویسی شی گرا PHP - ضمیمه 1: Type Hinting

درسنامه درس 11 از سری شی گرایی در PHP
php-oop-type-hinting

سلام و عرض ادب، اگر تا این قسمت از سری آموزشی برنامه نویسی شیء گرا در PHP پیش آمده اید به شما تبریک می گویم! شما تا این مرحله مفاهیم اصلی و پایه ای برنامه نویسی شیء گرا را یاد گرفته اید و با دانشی که از برنامه نویسی رویه ای نیز همراه دارید یک برنامه نویس خوب PHP هستید!

تنها کاری که برای شما مانده تمرین و کد نویسی زیاد است چرا که هیچ برنامه نویسی فقط با آموزش و بدون کد نویسی تربیت نمی شود! در این قسمت و چند قسمت آینده از برنامه نویسی شیء گرای PHP به سراغ برخی مباحث ریز، مباحث جا مانده و یا نکاتی که باز کردنشان در طول دوره صلاح دیده نشده خواهیم رفت.

Type Hinting چیست؟

Type hinting (در فارسی به معنی اشاره به نوع) قابلیتی در زبان PHP و بسیاری دیگر از زبان های برنامه نویسی است که از طریق آن می توانید تعیین کنید که انتظار چه نوع داده ای را داریم (آیا انتظار داریم برای آرگومان فلان تابع، یک آرایه به ما داده شود؟ آیا منتظر یک شیء هستیم؟ انتظار اینترفیس را داریم؟ و ...). استفاده از این قابلیت باعث می شود مدیریت کد ما بهتر و خطاهایی که برای ما ارسال می شود منظم تر باشند.

قابلیت type hinting در PHP 5 و PHP 7 برای آرایه ها و اشیاء موجود است اما در مورد داده های پایه ای (مانند اعداد صحیح، اعداد اعشاری، رشته ها و بولین ها) چنین قابلیتی را تنها در PHP 7 می بینیم. به شما توصیه می کنم حتما از PHP 7 به بالا استفاده کنید. زبان های برنامه نویسی برای شما آپدیت می شوند، برای چه از آنها استفاده نکنیم؟ این آپدیت ها امنیت وب سایت شما را نیز بالاتر می برند.

چطور type hinting را برای آرایه ها انجام دهیم؟

اگر می خواهید یک تابع فقط آرگومان های آرایه ای را قبول کند می توانید قبل از اسم پارامتر عبارت array را قرار دهید. syntax این حالت را در مثال زیر می بینید:

function functionName (array $argumentName)
{
  //code
}

آیا مثال ماشین را از جلسات قبل به خاطر دارید؟ اگر یادتان رفته است به جلسات قبل برگردید و آن را بخوانید. ما میتوانیم چنین کاری را با تابع ()calcNumMilesOnFullTank انجام دهیم. به مثال زیر توجه کنید:

// این تابع فقط یک آرایه را به عنوان آرگومان خود قبول می کند
function calcNumMilesOnFullTank(array $models)
{
  foreach($models as $item)
  {
    echo $carModel = $item[0];
    echo " : ";
    echo $numberOfMiles = $item[1] * $item[2];
    echo "<br />";
   }
}

حالا بیایید مقداری به تابع بدهیم که آرایه نباشد تا ببینیم چه اتفاقی می افتد:

calcNumMilesOnFullTank("Toyota");

ما اینجا رشته ی Toyota را به تابع دادیم. اگر چنین کاری کنید به خطای زیر برمیخورید:

Catchable fatal error: Argument 1 passed to calcNumMilesOnFullTank() must be of the type array, string given

می بینید که خطایی به ما برگردانده می شود و می گوید آرگومان ما از نوع آرایه نیست. منظور ما از خطاهای منظم تر نیز همین است؛ اگر نوع داده را تعیین نمی کردیم داده ی دیگری (به طور مثال یک رشته) وارد تابع می شد و با خطاهایی برمیخوردیم که شاید این چنین واضح نباشند و برای برطرف کردنشان با مشکل روبرو شویم.

بیایید این بار آرگومانی صحیح به تابع مان بدهیم و نتیجه را ببینیم:

$models = array(
  array('Toyota', 12, 44),
  array('BMW', 13, 41)
);
 
calcNumMilesOnFullTank($models);

عددهایی که در هر آرایه می بینید حجم باک ماشین و تعداد مایل هایی هستند که هر ماشین با یک گالون سوخت طی می کند.

نتیجه ی این کد می شود:

Toyota : 528
BMW : 533

نتیجه صحیح و سالم به ما تحویل داده می شود.

چطور type hinting را برای اشیاء انجام دهیم؟

این کار دقیقا شبیه به type hinting آرایه هاست با این تفاوت که به جای کلمه ی array قبل از نام پارامتر، باید از نام کلاسی که شیء از آن می آید استفاده شود. در مثال زیر constructor کلاس ما تنها می تواند اشیائی را بگیرد که از کلاس Driver ساخته شده باشند:

class Car {
  protected $driver;
 	
  // به پارامتر تابع دقت کنید
  public function __construct(Driver $driver)
  {
    $this -> driver = $driver;
  }
}
 
 
class Driver {}
 
 
$driver1 = new Driver();
$car1    = new Car($driver1);

آیا PHP از قابلیت Type Hinting برای داده های پایه ای پشتیبانی می کند؟

همانطور که گفته شد PHP 5 تنها از type hinting مربوط به آرایه ها و اشیاء پشتیبانی کرده اما PHP 7 از قابلیتی به نام scalar type hinting پشتیبانی می کند.

سوال: من از PHP 5 استفاده می کنم و به دلایلی فعلا نمی توانم آن را به PHP 7 ارتقاء دهم. راه چاره چیست؟

پاسخ: شما می توانید از توابع خانواده ی "is_" استفاده کنید. مهم ترین اعضای این خانواده را در لیست زیر می بینید:

  • is_bool : زمانی استفاده می شود که بخواهیم بدانیم فلان داده از نوع boolean (یعنی true یا false) است یا خیر.
  • is_int :  زمانی استفاده می شود که بخواهیم بدانیم فلان داده از نوع integer (عدد صحیح) است یا خیر.
  • is_float :  زمانی استفاده می شود که بخواهیم بدانیم فلان داده از نوع float (عدد اعشاری) است یا خیر.
  • is_string :  زمانی استفاده می شود که بخواهیم بدانیم فلان داده از نوع string (زشته) است یا خیر.
  • is_null :  زمانی استفاده می شود که بخواهیم بدانیم فلان داده از نوع null است یا خیر.

چطور از قابلیت scalar type hinting در PHP 7 استفاده کنم؟

scalar type hinting از انواع داده ی integers, floats, strings, booleans پشتیبانی می کند. مثال زیر تمام این موارد را در خود آورده است:

class car {
  protected $model;
  protected $hasSunRoof;
  protected $numberOfDoors;
  protected $price;

  // برای رشته ها type hinting
  public function setModel(string $model)
  {
    $this->model = $model;
  }

  // برای بولین ها type hinting
  public function setHasSunRoof(bool $value)
  {
    $this->hasSunRoof = $value;
  }

  // برای اعداد صحیح type hinting
  public function setNumberOfDoors(int $value)
  {
    $this->numberOfDoors = $value;
  }

  // برای اعداد اعشاری type hinting
  public function setPrice(float $value)
  {
    $this->price = $value;
  }        
}

چند کلام حرف خودمانی

ابتدا قصد داشتیم که مباحث رابط PDO (ارتباط شیء گرا با پایگاه داده) را در ادامه ی همین آموزش ها، یعنی سری آموزشی برنامه نویسی شیء گرا در PHP، بیاوریم اما پس از بررسی بیشتر تصمیم گرفتیم مبحث PDO را به صورت یک سری آموزشی جداگانه در بیاوریم. دلیل این تصمیم این بوده است که مبحث PDO بیشتر از آن که به شیء گرایی مربوط باشد به پایگاه داده مربوط است (به غیر از مطالبی که در همین دوره ذکر شد، مبحث یا ساختار دستوری جدیدی در زمینه ی شیء گرایی ندارد) و از طرفی باید به صورت مفصل توضیح داده شده و با روش های غیر شیء گرا نیز مقایسه شود. چنین کاری چندین و چند قسمت جداگانه لازم دارد و از همین رو پس از پایان ضمیمه ها در این سری آموزشی، در یک سری آموزشی جداگانه، به سراغ آن خواهیم رفت. به هر حال امیدوارم از این قسمت لذت برده باشید.

در پناه حق

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری شی گرایی در PHP توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما (1 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

Amir
23 مهر 1399
تابع اگر وروودی interface بگیره چجوری پیاده سازی میشه؟

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.