PHP魔术变量和魔术方法
魔术变量
1.__FILE__
当前运行文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。
魔术方法
1.__sleep()和__weekup():执行serialize()前调用类里的__sleep()方法,并返回数组(去掉不必要的属性),
执行unserialize()前调用__wakeup()方法,并返回序列化后需要增加的属性。
用法:下面例子显示了如何用__sleep和 __wakeup方法来串行化一个对象. Id属性是一个不打算保留在对象中的临时属性. __sleep方法保证在串行化的对象中不包含id属性. 当反串行化一个User对象,__wakeup方法建立id属性的新值. 这个例子被设计成自我保持. 在实际开发中,你可能发现包含资源(如图像或数据流)的对象需要这些方法。
<?php class user { public $name; public $id; function __construct() { // 给id成员赋一个uniq id $this->id = uniqid(); } function __sleep() { //此处不串行化id成员 return(array('name')); } function __wakeup() { $this->id = uniqid(); } } $u = new user(); $u->name = "Leo"; $s = serialize($u); //serialize串行化对象u,此处不串行化id属性,id值被抛弃 $u2 = unserialize($s); //unserialize反串行化,id值被重新赋值 //对象u和u2有不同的id赋值 echo "<pre>"; print_r($u); print_r($s);//直接没有id print_r($u2); //echo "<pre>";print_r(spl_); ?>
输出:
user Object
(
[name] => Leo
[id] => 5538a94e581cc
)
O:4:"user":1:{s:4:"name";s:3:"Leo";}user Object
(
[name] => Leo
[id] => 5538a94e581fe
)
2.__clone():执行一个前拷贝,基本类型属性传值,对象类型属性传引用。故如果对象类型也要传值,则在类中增加__clone(){$this->balence = clone $this->balence; }.
<?php class Balance{ public $count = 0; function __construct($count){ $this->count = $count; } } class P extends Balance{ public $balence; function __construct(Balance $balence){ $this->balence = $balence; } function __clone(){ $this->balence = clone $this->balence; } } $p = new P(new Balance(300)); $p2 = clone $p; $p2->balence->count = 32; echo "<pre>";var_dump($p,$p2); ?>
输出:
object(P)#1 (2) { ["balence"]=> object(Balance)#2 (1) { ["count"]=> int(300) } ["count"]=> int(0) } object(P)#3 (2) { ["balence"]=> object(Balance)#4 (1) { ["count"]=> int(32) } ["count"]=> int(0) }
3.__autoload();自动加载类,必须每次都include类文件。 自动加载不可用于 PHP 的 CLI 交互模式。
说明:该魔术方法试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。
文件1:1.php
<?php function __autoload($class){ $file = $class.".php"; include_once($file); } $animal = new Animal(); ?>
文件2:Animal.php (文件名必须和该类名一致)
<?php class Animal{ function __construct(){ echo "this class is inited successful!"; } } ?>
spl_autoload_register() 提供了一种更加灵活的方式来实现类的自动加载。因此,不再建议使用 __autoload() 函数,在以后的版本中它可能被弃用。
<?php /** * $class : 不用给该变量赋值,因为在new这个对象的时候, * 会被自动填充进去。 */ if(!function_exists('classAutoLoader')){ function classAutoLoader($class){ $class=strtolower($class); $classFile=$class.'.php'; if(is_file($classFile)&&!class_exists($classFile)) include $classFile; } } $r = spl_autoload_register('classAutoLoader'); var_dump($r); $a = new Animal(); ?>
匿名函数:
<?php spl_autoload_register(function ($class){include $class.'.php';}); $p = new Animal(); ?>