魔术方法
2022-10-19 08:50:48内容摘要
__construct, __destruct (参看 构造方法和析构方法), __call, __callStatic, __get, __set, __isset, __unset (参看 重载), __sleep, __wakeup, __toString, __set_state 和 __clone 等方法在PHP中被称为“魔术方法”(Magic methods)。 你在命名自己的类方法时不能使用这些方法名。
文章正文
魔术方法
__construct, __destruct (参看 构造方法和析构方法), __call, __callStatic, __get, __set, __isset, __unset (参看 重载), __sleep, __wakeup, __toString, __set_state 和 __clone 等方法在PHP中被称为“魔术方法”(Magic methods)。 你在命名自己的类方法时不能使用这些方法名。Caution
PHP把所有以__(两个下划线)开头的类方法当成魔术方法。所以你定义自己的类方法时,不要以 __为前缀。
__sleep 和 __wakeup
serialize() 函数会检查是否存在一个魔术方法 __sleep.如果存在,__sleep()方法会先被调用, 然后才执行序列化操作。这个功能可以用于清理对象,并返回一个包含对象中所有变量名称的数组。如果该方法不返回任何内容,则NULL被序列化,导致 一个E_NOTICE错误。
__sleep方法常用于提交未提交的数据,或类似的操作。同时,如果你有一些很大的对象, 不需要保存,这个功能就很好用。
与之相反,unserialize()会检查是否存在一个__wakeup方法。如果存在,则会先调用 __wakeup方法,预先准备对象数据。
__wakeup经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。
Example #1 Sleep 和 wakeup
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <code><?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(); } } ?></code> |
__toString
The __toString method allows a class to decide how it will react when it is converted to a string. __toString 方法可以让一个类决定它如何转换成一个字符串。
Example #2 简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <code><?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 ; ?></code> |
以上例程会输出:
1 | Hello |
__invoke
当尝试以调用函数的方式调用一个对象时,__invoke 方法会被自动调用。
Note:
本特性只在PHP 5.3.0 及以上版本有效。
Example #3 Using __invoke
1 2 3 4 5 6 7 8 9 10 | <?php class CallableClass { function __invoke( $x ) { var_dump( $x ); } } $obj = new CallableClass; $obj (5); var_dump( is_callable ( $obj )); ?> |
以上例程会输出:
1 2 | int(5) bool(true) |
__set_state
当调用var_export()时,这个静态 方法会被调用(自PHP 5.1.0起有效)。本方法的唯一参数是一个数组,其中包含按array('property' => value, ...)格式排列的类属性。
Example #4 Using __set_state (PHP 5.1.0及更高版本支持)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <code><?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 ); ?></code> |
以上例程会输出:
1 2 3 4 5 6 | object(A)#2 (2) { [ "var1" ]=> int(5) [ "var2" ]=> string(3) "foo" } |
代码注释