یادآوری از OOP (بخش دوم)

(An Overview of PHP Object-Oriented Programming (Part 2

23 شهریور 1398
پروژه ساخت شبکه ی اجتماعی: یادآوری از OOP (بخش دوم)

کار با Constructor و Deconstructor

برای شروع این جلسه فایلی به نام 2_4.php بسازید تا کدهایمان را در آن بنویسیم. مانند جلسه قبل یک کلاس به نام user تعریف کرده و برای آن دو خصوصیت (property) قرار می دهیم؛ نام و سن. سپس متد sayHello را دوباره می نویسیم (ر.ک به جلسه قبل) و یک نمونه از این کلاس را می سازیم:

class User {
    public $name;
    public $age;
    public function sayHello(){
      return $this->name . ' Says Hello';
    }
}
$user1 = new User ();

اگر یادتان باشد در جلسه قبل به صورت مستقیم و با دستور زیر نام (name) را تغییر می دادیم:

$user1->name = 'Brad';

اما این روش اصلا روش خوبی نیست و برای تغییر دادن یک خصوصیت بهتر است از constructor استفاده کنیم. constructor ها در اصل متدهایی هستند که هنگام نمونه سازی (ساختن یک شیء از یک کلاس) به طور خودکار اجرا می شوند. به طور مثال اگر یک constructor به شکل زیر بنویسیم:

public function __construct (){
		echo 'constructor ran ...';
	}

هر بار که شیء ای بسازیم (دستور ;()user1 = new User$ ) این constructor هم اجرا شده و پیام ... constructor ran را در مرورگر نمایش می دهد. به نظر شما از چه طریقی می توان با این روش نام کاربر را تغییر داد؟

constructor ها می توانند پارامترهایی بگیرند بنابراین می توانیم پارامترهای نام و سن را به این constructor بدهیم تا در هنگام ساخت شیء آن ها را تعریف کنیم. به طور مثال به کد زیر نگاه کنید:

 public function __construct($name, $age){
      $this->name = $name;
      $this->age = $age;
    }

در اینجا به constructor خود متغیرهای نام و سن را پاس داده ایم. سپس درون constructor گفته ایم که متغیرهای نام و سن باید همان مقداری باشند که بعدا به constructor پاس داده خواهند شد (هنگام ساخت یک شیء - نمونه سازی). بنابراین اگر کد زیر را بنویسیم:

public function __construct($name, $age){
      $this->name = $name;
      $this->age = $age;
    }

  $user1 = new User('Brad', 36);
  echo $user1->name . ' is ' . $user1->age . ' years old'; 

قسمت اول این کد که constructor هست و توضیح داده شده است اما قسمت بعدی (new User) قسمتی است که از کلاس یک نمونه شیء ساخته ایم و نام آن را Brad و سن این فرد را 36 سال قرار داده ایم (سن یک عدد است بنابراین آن را داخل quotation نمی گذاریم). تا اینجا فقط یک شیء از کلاس user ساخته ایم بنابراین چیزی در مرورگر نمایش داده نمی شود. برای گرفتن خروجی از این کد می توانیم از خط آخر مثال بالا استفاده کنیم که عبارت زیر را در مرورگر نمایش می دهد:

Brad is 36 years old. (یعنی برد 36 ساله است)

همچنین اگر می خواهید متد say hello را صدا بزنید می توانید با دستور زیر این کار را انجام دهید:

  echo $user1->sayHello();

با این کار عبارت Brad says hello نمایش داده می شود. چرا؟ به این دلیل که از قبل و هنگام ساخت شیء user1 نام آن را Brad تعیین کرده ایم و تا آخر نیز نام این کاربر Brad خواهد بود. برای تمرین بیشتر یک کاربر دیگر هم می سازیم:

$user2 = new User('Sara', 25);
  echo $user2->name . ' is ' . $user2->age . ' years old'; 
  echo $user2->sayHello();

مسئله بعدی Deconstruct است. Deconstruct زمانی اجرا می شود که هیچ ارجاعی به شیء خاصی نداشته باشیم. از Deconstruct معمولا برای بستن اتصالات پایگاه داده و پاک سازی حافظه و... استفاده می شود. به Deconstruct زیر توجه کنید:

public function __destruct(){
      echo 'destructor ran...';
    }

کد ما تا این لحظه بدین شکل است:

<?php
  class User {
    public $name;
    public $age;

    // زمانی اجرا می شود که شیء ای ساخته می شود
    public function __construct($name, $age){
      $this->name = $name;
      $this->age = $age;
    }
	
	public function __construct (){
		echo 'constructor ran ...';
	}

    public function sayHello(){
      return $this->name . ' Says Hello';
    }

    // زمانی اجرا می شود که هیچ اشاره و ارجاعی به شیء خاصی نباشد
    // برای پاک سازی و بستن اتصالات پایگاه داده استفاده می شود
    public function __destruct(){
      echo 'destructor ran...';
    }
  }

  $user1 = new User('Brad', 36);
  echo $user1->name . ' is ' . $user1->age . ' years old'; 
  echo '<br>';
  echo $user1->sayHello();

  echo '<br>';

  $user2 = new User('Sara', 25);
  echo $user2->name . ' is ' . $user2->age . ' years old'; 
  echo '<br>';
  echo $user2->sayHello();

حالا باید از خودتان بپرسید که چه زمانی deconstruct اجرا می شود؟

ما گفتیم deconstruct زمانی اجرا می شود که هیچ ارجاع یا اشاره ای به کلاس یا شیء مورد نظر وجود نداشته باشد بنابراین عبارت ...destructor ran پس از نمایش بقیه خروجی نمایش داده می شود:

Brad is 36 years old

Brad Says Hello

Sara is 25 years old

Sara Says hello

deconstructor ran...

deconstructor ran...

اشتباه برنامه نویسان تازه کار این است که تصور می کنند از آنجایی که کد deconstructor قبل از کدهای خروجی sara و brad آمده است بنابراین قبل از آن ها هم اجرا می شود اما اینچنین نیست. deconstruct زمانی اجرا می شود که هیچ ارجاع یا اشاره ای به کلاس یا شیء مورد نظر وجود نداشته باشد چرا که معمولا در آن کد های قطع اتصال به پایگاه داده و... نوشته می شود؛ اگر این کدها وسط برنامه اجرا شوند تمام برنامه ما به هم خواهد ریخت.

همچنین اگر توجه کنید می بینید که کد deconstruct دو بار اجرا شده است. دلیلش این است که ما دو نمونه از کلاس را ساخته ایم و گفتیم که deconstructor (مانند constructor) با هر بار ساخته شدن یک شیء، یک بار اجرا می شود.

نکته آخری که می خواهیم در مورد آن صحبت کنیم یک ثابت جادویی (magic constant) به نام __class__ است. بهتر است در قالب مثال با آن آشنا شوید:

public function __construct($name, $age){
      echo 'Class ' . __CLASS__ . ' instantiated<br>';
      $this->name = $name;
      $this->age = $age;
    }

در اینجا کد constructor خود را کمی تغییر داده و ثابت جادویی __CLASS__ را به آن اضافه کرده ایم. خروجی این دستور عبارت زیر خواهد بود:

Class User instantiated

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

نکته: به construct__ و deconstruct__ متدهای جادویی (magic methods) می گویند.

امیدوارم از این قسمت لذت برده باشید.

دانلود فایل کدها تا این جلسه

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش ساخت شبکه اجتماعی توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

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