PHP的魔术方法学习
PHP的魔术方法学习
__set_state()var_export可以把一个集合导出为一串字符串,这些字符串是一些可执行的PHP代码。在php5.1.0的面向对象里,引入了一个叫__set_state的静态方法来使得var_export支持对象实例的导出。当用var_export导出一个实例的时候,所导出字符串里,是调用这个静态方法的代码。这个方法有一个参数,为包含所导出的实例的所有成员属性的一个数组。有点抽象,看下面的例子吧。
<?phpclass o{ public $skill=’php’; public static function __set_state($arr) { foreach ($arr as $k => $v) { $obj->$k = $v; } return $obj; }}$i = new o;$i->age = 21;eval(’$b = ’.var_export($i,true).’;’);//这里的true表示var_export返回所导出的字符串,而不是把它打印出来。print_r($b);/*输出:stdClass Object( [skill] => php [age] => 21)*/?>
__clone()
在php5里,对象间的赋值总是以地址引用来传递的。例如下面这个例子,将会输出66,而不是55.
<?phpclass o{ public $age = 55;}$i = new o;$i2 = $i;$i->age = 66;echo $i2->age;?>
如果要以实际值来传递,则需要用到clone关键词。
<?phpclass o{ public $age = 55;}$i = new o;$i2 = clone $i;$i->age = 66;echo $i2->age;//输出55?>
但是,这里clone的只是$i这个实例。如果$i的某个成员属性也是个实例,那么这个成员属性还是会以引用方法被传递到$i2的。例如下面这个例子:
<?phpclass o{ public $age = 55; public $sub = null;}class o2{ public $p=1;}$i = new o;$i->sub=new o2;$i2 = clone $i;$i->sub->p=5;echo $i2->sub->p;?>
最后输出的是5,而不是1。也就是说,$i和$i2虽然不是指向的虽然不是同一个实例,但是它们的成员属性$sub却是指向同一个实例。这时候,我们必须借助__clone这个方法来对$sub进行复制。在o类里,加入__clone()方法。如下:
<?phpclass o{ public $age = 55; public $sub = null; public function __clone() { $this->sub=clone $this->sub; }}//......?>
这样,在echo $i2->sub->p;的时候,输出的就是传递时候的值1了。
__autoload()
当创建一个实例化的时候,如果对应的类不存在,__autoload()将会被执行,这个函数有一个参数,为所要创建的实例对应的类名。在下面的例子里,当创建一个test类的实例的时候,如果/home/surfchen/project/auto.php存在,则require这个文件,否则打印一个Class test Not Found的错误,并中止当前脚本。