<?phpclass FileRead{protected $handle = NULL;function __construct(){$this->handle = fopen(...);}function __destruct(){fclose($this->handle);}}?>
这两个方法在继续时可以扩展,例如:
<?phpclass TmpFileRead extends FileRead{function __construct(){parent::__construct();}function __destruct(){parent::__destruct();}}?>
__call()和__callStatic()
在工具中调用一个不可访问方法时会调用这两个方法,后者为静态方法。这两个方法我们在可变方法(Variable functions)调用中可能会用到。
<?phpclass MethodTest{public function __call ($name, $arguments) {echo "Calling object method '$name' ". implode(', ', $arguments). "\n";}public static function __callStatic ($name, $arguments) {echo "Calling static method '$name' ". implode(', ', $arguments). "\n";}}$obj = new MethodTest;$obj->runTest('in object context');MethodTest::runTest('in static context');?>
__get(),__set(),__isset()和__unset()
当get/set一个类的成员变量时调用这两个函数。例如我们将工具变量保存在其余一个数组中,而不是工具本身的成员变量

<?phpclass MethodTest{private $data = array();public function __set($name, $value){$this->data[$name] = $value;}public function __get($name){if(array_key_exists($name, $this->data))return $this->data[$name];return NULL;}public function __isset($name){return isset($this->data[$name])}public function unset($name){unset($this->data[$name]);}}?>
__sleep()和__wakeup()
当我们在实行serialize()和unserialize()时,会先调用这两个函数。例如我们在序列化一个工具时,这个工具有一个数据库链接,想要在反序列化中规复链接状态,则可以通过重构这两个函数来实现链接的规复。例子如下:
<?phpclass 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()
工具当成字符串时的回应方法。例如利用echo $obj;来输出一个工具
<?php// Declare a simple classclass TestClass{public function __toString() {return 'this is a object';}}$class = new TestClass();echo $class;?>
这个方法只能返回字符串,而且不可以在这个方法中抛出非常,否则会涌现致命缺点。
__invoke()调用函数的办法调用一个工具时的回应方法。如下
<?phpclass CallableClass{function __invoke() {echo 'this is a object';}}$obj = new CallableClass;var_dump(is_callable($obj));?>
__set_state()
调用var_export()导出类时,此静态方法会被调用。
<?phpclass A{public $var1;public $var2;public static function __set_state ($an_array) {$obj = new A;$obj->var1 = $an_array['var1'];$obj->var2 = $an_array['var2'];return $obj;}}$a = new A;$a->var1 = 5;$a->var2 = 'foo';var_dump(var_export($a));?>
__clone()
当工具复制完成时调用。例如在设计模式详解及PHP实现:单例模式一文中提到的单例模式实现办法,利用这个函数来防止工具被克隆。
<?phppublic class Singleton {private static $_instance = NULL;// 私有布局方法private function __construct() {}public static function getInstance() {if (is_null(self::$_instance)) {self::$_instance = new Singleton();}return self::$_instance;}// 防止克隆实例public function __clone(){die('Clone is not allowed.' . E_USER_ERROR);}}?>
魔术常量(Magic constants)
PHP中的常量大部分都是不变的,但是有8个常量会随着他们所在代码位置的变革而变革,这8个常量被称为魔术常量。
__LINE__,文件中确当前行号__FILE__,文件的完全路径和文件名__DIR__,文件所在的目录__FUNCTION__,函数名称__CLASS__,类的名称__TRAIT__,Trait的名字__METHOD__,类的方法名__NAMESPACE__,当前命名空间的名称这些魔术常量常常被用于获得当前环境信息或者记录日志。