آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
مشکل عدم دسترسی خریداران پیشین به برخی آموزش ها برطرف شد
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

متد های جادویی (Magic Methods)

محسن موحد  9 سال پیش  8 سال پیش
+15 0

Constructor :

یکی از متد های جادویی construct__ هست.
در زمان ساخت آبجکت از یک کلاس , این متد اجرا میشه.

class BaseClass
{
   public function __construct()
   {
       echo "In BaseClass constructor";
   }
}

// In BaseClass constructor
$obj = new BaseClass();  // __construct() will be run

زمان new عبارت "In BaseClass constructor" چاپ میشه.
حالا کلاسی دیگه میسازیم که از BaseClass مشتق شده باشه و متد construct رو در خودش داره:

class SubClass extends BaseClass
{
   function __construct()
   {
       parent::__construct();
       echo "In SubClass constructor";
   }
}

// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();

* با دستور parent میتونیم متد های کلاس والد رو فراخوانی کنیم:

 parent::MethodName


در حالت بعدی کلاسی مشتق شده از BaseClass داریم ولی این کلاس متد construct نداره:

class OtherSubClass extends BaseClass
{
    // inherits BaseClass's constructor
}

// In BaseClass constructor
$obj = new OtherSubClass();

این کلاس , چون متد construct نداره , از والد خودش (BaseClass) این متدو به ارث میبره.

نوع دیگری برای پیاده سازی constructor , ساخت یک متد همنام با کلاس:

class Bar
{
    public function Bar()
    {
        echo "In Bar constructor";
    }
}

// In Bar constructor
$obj = new Bar();
 برای این سوال 3 پاسخ وجود دارد.
پاسخ به سوال 
محسن موحد  9 سال پیش
+5 0

Destructor :

متد جادویی دیگری که در php تعریف شده destruct__ هست.

این متد در زمان از بین رفتن آبجکت یا به پایان رسیدن اسکریپت , اجرا میشود.

class Example
{
   public function __construct()
   {
       print "In constructor<br>";
       $this->name = "Example";
   }

   public function __destruct()
   {
       echo "Destroying " . $this->name;
   }
}

$obj = new Example();

نتیجه ای که میبینیم:

In constructor
Destroying Example

شاید بنظرتون برسه دو متد , با ساخت آبجکت , همزمان اجرا شدن ولی دلیل اجرای destructor به پایان رسیدن اسکریپت هست.

واسه نشون دادن این مسئله , یک مثال دیگه میزنم:

class Example
{
   public function __construct()
   {
       print "In constructor<br>";
       $this->name = "Example";
   }

   public function __destruct()
   {
       echo "Destroying " . $this->name;
   }
}

$obj = new Example();

echo 'Numbers: '; for($i = 1; $i <= 10; $i++) { echo $i . ' '; } echo '<br>';

نتیجه ی حاصل از اسکریپت بالا:

In constructor
Numbers: 1 2 3 4 5 6 7 8 9 10 
Destroying Example


مورد دیگه ای که در اول متن گفتم , اجرای destructor در زمان از بین رفتن آبجکت:

class Example
{
   public function __construct()
   {
       print "In constructor<br>";
       $this->name = "Example";
   }

   function __destruct()
   {
       echo "Destroying " . $this->name;
   }
}

$obj = new Example();

echo 'Numbers:<br>';

unset($obj); // __destruct() will be run

echo '<br>';
for($i = 1; $i <= 10; $i++)
{
	echo $i . ' ';
}
echo '<br>';

نتیجه ی اسکریپت:

In constructor
Numbers:
Destroying Example
1 2 3 4 5 6 7 8 9 10 

همونطور که میبینید , با استفاده از تابع unset , آبجکت کلاس رو حذف کردیم که باعث فراخوانی متد destructor شد.

پاسخ به سوال 
محسن موحد  9 سال پیش
+4 0

Getter :

متد get__ در زمان خواندن یک فیلد , اجرا میشود.

class Example
{
	private $name;
	private $family;

	public function __construct()
	{
		$this->name = 'Mohsen';
		$this->family = 'Movahed';
	}
}

$obj = new Example();
echo $obj->name . ' ' . $obj->family; // error

نتیجه با اررور مواجه میشه.متن اررور:

Error: Cannot access private property Example::$name

علت: فیلد های private , بیرون از کلاس قابل دسترسی نیستن.

حالا با توجه به تعریفی که از getter داشتیم , زمان صدا زدن فیلد (echo $obj->name) , متد get__ (در صورتی که تعریف شده باشه) , اجرا میشه:

class Example
{
	private $name;     // field 1
	private $family;   // field 2

	public function __construct()
	{
		$this->name = 'Mohsen';
		$this->family = 'Movahed';
	}

	public function __get($field)
	{
		return $this->$field;
	}
}

$obj = new Example();
echo $obj->name . ' ' . $obj->family; // Mohsen Movahed

//****************OR******************//

$obj = new Example();
$name = $obj->name; // __get() will be run
$family = $obj->family; // __get() will be run

echo $name . ' ' . $family; // Mohsen Movahed

حالا با وجود متد get , فیلدها از داخل خود کلاس مورد دستیابی قرار میگیرن و در چاپ نام و فامیل ,  این متد دو بار اجرا میشود.

***************************************************

Setter :

متد set__ در زمان مقدار دهی فیلدها اجرا خواهد شد.
دو آرگومان داره: 

  1. نام فیلد
  2. مقدار
class Example
{
	private $name;     // field 1
	private $family;   // field 2

	public function __get($field)
	{
		return $this->$field;
	}

	public function __set($field, $value)
	{
		$this->$field = $value;
	}
}

$obj = new Example();

$obj->name = 'Mohsen';        // __set() will be run
$obj->family = 'Movahed';     // __set() will be run
echo $obj->name . ' ' . $obj->family; // Mohsen Movahed

 

پیاده سازی getter و setter به روشی دیگر: (برای مثال)

class Example
{
	private $fields;

	public function __construct()
	{
		$this->fields = array(
			'name' => null,
			'family' => null,
			'age' => null,
		);
	}

	public function __get($key)
	{
		if(array_key_exists($key, $this->fields))
		{
			return $this->fields[$key];
		}
		return false;
	}

	public function __set($key, $value)
	{
		if(array_key_exists($key, $this->fields))
		{
			$this->fields[$key] = $value;
		}
	}
}

$obj = new Example();

$obj->name = 'Mohsen';
$obj->family = 'Movahed';
$obj->age = 23;
$obj->email = 'l3iidak@yahoo.com';

echo $obj->name . ' ' . $obj->family . ' ' . $obj->age . ' ' . $obj->email; // Mohsen Movahed 23

email جزو ایندکس ها نیست , بنابراین مقدار دهی نمیشود.
* به شکل های مختلف و اعتبار سنجی ها متفاوت میتونید این دو متدو پیاده سازی کنید.

0 0
چرا email جزو ایندکس ها نیست و مقدارش در خروجی نشون داده نشد مگه name, family , age جزو ایندکس ها بودند اصلا این ایندکسی که می گی یعنی چی می تونید بیشتر توضیح بدید من متوجه نشدم؟ (8 سال پیش)
پاسخ به سوال 
محسن موحد  9 سال پیش
+5 0

Call :

وقتی توسط یک آبجکت , متدی رو فراخوانی کنیم که در کلاس مورد نظر وجود نداشته باشد , متد call__ اجرا میشود.

دو آرگومان دارد:

  1. نام متد
  2. آرگومان های ارسالی
class MethodTest
{
    public function __call($method, $arguments)
    {
        // Note: value of $mthod is case sensitive.
        echo "Calling object method <strong>'$method'</strong> with arguments:<br>";
        echo '<pre>'. print_r($arguments, true) .'</pre>';
    }

    public function display()
    {
    	echo 'Display Method' . '<br>';
    }
}

$obj = new MethodTest();
$obj->display(); // Display Method
$obj->runTest(1, 2, 3, 4);


متدهایی که در کلاس وجود دارند , اگر فراخوانی شوند خود متد ها اجرا می شوند , بنابراین متد display اجرا میشود.
اما چون متد runTest در کلاس وجود ندارد , متد Call__ اجرا میشود. (نام متد: runTest - آرگومان ها : 1 , 2 , 3 , 4)

نتیجه ی کد بالا:

Display Method
Calling object method 'runTest' with arguments:
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
)

 

***************************************************


callStatic :

متد callStatic__ هم مانند متد call__ عمل میکند با این تفاوت که برای متد های استاتیک هست.

 

class MethodTest
{
    public static function __callStatic($method, $arguments)
   {
       // Note: value of $method is case sensitive.
       echo "Calling static method <strong>'$method'</strong> with arguments: " 
. implode(', ', $arguments) . PHP_EOL; } } MethodTest::runTest('in static context');

نتیجه:

 Calling static method 'runTest' with arguments: in static context
0 0
اقا دستت درد نکنه خوب بود ولی فکر کنم متدهای دیگه ای هم داره اگه وقت کردید اینجا قرار بدید خیلی خوب می شه باز هم ممنون امیدوارم موفق باشید (8 سال پیش)

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .