نامهای تابع __construct, __destruct, __call, __callStatic, __get, __set, __isset, __unset, __sleep, __wakeup, __toString, __invoke, __set_state و __clone در کلاسهای PHP جادویی هستند. شما نمیتوانید نام این توابع را در کلاس خود بکار برید مگر بخواهید عملکرد جادویی همراه آنها را داشته باشید.
PHP تمام نامهای توابع با شروع __ را رزرو نموده است تا جادویی باشند. توصیه میگردد نامهای تابع با شروع __ در PHP استفاده نکنید مگر عملکرد جادویی مستند آن را بخواهید.
serialize() بررسی میکند آیا کلاس تابعی جادویی با نام __sleep دارد. اگر این چنین است آن تابع پیش از هرگونه سریالسازی اجرا میگردد. میتواند شی را تمیز کرده و یک آرایه با نام تمام متغیرهای آن شی که باید سریالسازی شوند باز میگرداند. اگر متد مقداری باز نمیگرداند NULL سریالسازی شده و E_NOTICE صادر میگردد.
Note:
بازگرداندن نام ویژگیهای private در کلاس والد برای __sleep ممکن نیست. انجام این کار خطای سطحE_NOTICE ایجاد میکند. به جای آن شما باید از واسط Serializable استفاده کنید.
استفاده مورد نظر __sleep اعمال داده منتظر یا کارهای تمیزکاری است. همچنین تابع اگر شما یک شی بزرگ داشته باشید که نمیخواهید تمام آن را ذخیره کنید مفید است.
برعکس unserialize() بررسی مینماید آیا تابعی جادویی با نام __wakeup وجود دارد. اگر موجود باشد این تابع برای بازسازی منابع بکار میرود.
استفاده مورد نظر از __wakeup برقراری ارتباط پایگاه داده است که در طول سریالسازی از دست رفته است و کارهای اولیه آن را دوباره انجام دهد.
Example #1 خواب و بیداری
<?php
class Connection {
protected $link;
private $server, $username, $password, $db;
public function __construct($server, $username, $password, $db)
{
$this->server = $server;
$this->username = $username;
$this->password = $password;
$this->db = $db;
$this->connect();
}
private function connect()
{
$this->link = mysql_connect($this->server, $this->username, $this->password);
mysql_select_db($this->db, $this->link);
}
public function __sleep()
{
return array('server', 'username', 'password', 'db');
}
public function __wakeup()
{
$this->connect();
}
}
?>
متد __toString به یک کلاس امکان تصمیمگیری درباره چگونگی رفتار در تبدیل به یک رشته میدهد.
Example #2 مثال ساده
<?php
// Declare a simple class
class TestClass
{
public $foo;
public function __construct($foo) {
$this->foo = $foo;
}
public function __toString() {
return $this->foo;
}
}
$class = new TestClass('Hello');
echo $class;
?>
The above example will output:
Hello
توجه به این نکته لازم است که پیش از PHP 5.2.0 متد __toString تنها زمانی فراخوانی میٰشود که مستقیما با echo() یا print() ترکیب شده باشد. از زمان PHP 5.2.0 در هر متن رشتهای فراخوانی میشود (به عنوان نمونه در printf() با تغییردهنده %s) اما در انواع متون دیگر (برای نمونه با تغییردهنده%d)فراخوانی نمیشود. از زمان PHP 5.2.0 تبدیل اشیا بدون متد __toString به رشته یک E_RECOVERABLE_ERROR ایجاد خواهد کرد.
متد __invoke هنگام فراخوانی یک شی به صورت تابع فراخوانی میشود.
Note:
این ویژگی از PHP 5.3.0 فراهم شده است.
Example #3 استفاده از __invoke
<?php
class CallableClass {
function __invoke($x) {
var_dump($x);
}
}
$obj = new CallableClass;
$obj(5);
var_dump(is_callable($obj));
?>
The above example will output:
int(5) bool(true)
این متد static برای کلاسهای ارسال شده با var_export() از زمان PHP 5.1.0 فراخوانی میگردد.
تنها پارامتر این متد یک آرایه شامل ویژگیهای ارسال شده در فرم array('property' => value, ...) است.
Example #4 استفاده از __set_state (از زمان PHP 5.1.0)
<?php
class A
{
public $var1;
public $var2;
public static function __set_state($an_array) // As of PHP 5.1.0
{
$obj = new A;
$obj->var1 = $an_array['var1'];
$obj->var2 = $an_array['var2'];
return $obj;
}
}
$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';
eval('$b = ' . var_export($a, true) . ';'); // $b = A::__set_state(array(
// 'var1' => 5,
// 'var2' => 'foo',
// ));
var_dump($b);
?>
The above example will output:
object(A)#2 (2) { ["var1"]=> int(5) ["var2"]=> string(3) "foo" }