# php魔术方法 魔术方法 | 方法用途| 触发机制|示例 ---|---|---|--- __contract | 构造函数 | 示例化类时自动触发 | [示例](#contract) __destruct | 析构函数 | 销毁类时自动触发 | [示例](#destruct) __call() | 方法重载 | 对象中调用一个不可访问方法时自动触发| [示例](#call) __callStatic() | 静态方法重载 | 静态上下文中调用一个不可访问方法时自动触发| [示例](#callstatic) __get() | 访问属性 | 访问一个不存在或者私有属性时触发 | [示例](#get) __get() | 设置属性 | 设置一个不存在或者私有属性时触发 | [示例](#set) __toString() | 以字符串输出这个类 | 以字符串输出这个类时触发 | [示例](#tostring) # contract ```php <?php class BaseClass { function __construct() { print "In BaseClass constructor\n"; } } class SubClass extends BaseClass { function __construct() { parent::__construct(); print "In SubClass constructor\n"; } } class OtherSubClass extends BaseClass { // inherits BaseClass's constructor } // In BaseClass constructor $obj = new BaseClass(); // In BaseClass constructor // In SubClass constructor $obj = new SubClass(); // In BaseClass constructor $obj = new OtherSubClass(); ``` --- # destruct 析构函数即使在使用 exit() 终止脚本运行时也会被调用。在析构函数中调用 exit() 将会中止其余关闭操作的运行。 ```php //试图在析构函数(在脚本终止时被调用)中抛出一个异常会导致致命错误。 <?php class MyDestructableClass { function __construct() { print "In constructor\n"; $this->name = "MyDestructableClass"; } function __destruct() { print "Destroying " . $this->name . "\n"; } } $obj = new MyDestructableClass(); ``` --- # call `$name`参数是要调用的方法名称。`$arguments`参数是一个枚举数组,包含着要传递给方法 $name 的参数。 ```php <?php class MethodTest { public function __call($name, $arguments) { // 注意: $name 的值区分大小写 echo "Calling object method '$name' " . implode(', ', $arguments). "\n"; } } $obj = new MethodTest; $obj->runTest('in object context'); ``` --- # callStatic `$name`参数是要调用的方法名称。`$arguments`参数是一个枚举数组,包含着要传递给方法`$name`的参数。 ```php <?php class MethodTest { /** PHP 5.3.0之后版本 */ public static function __callStatic($name, $arguments) { // 注意: $name 的值区分大小写 echo "Calling static method '$name' " . implode(', ', $arguments). "\n"; } } $obj = new MethodTest; MethodTest::runTest('in static context'); ``` --- # get 在程序运行过程中,通过它可以在对象的外部获取私有成员属性的值。或者未定义的成员属性 ```php <?php class OOP { public function __get($name) { echo 'get key: '.$name; } } $oop = new OOP(); $oop->name;// output: get key: name ``` # set __set($name, $value)方法用来设置私有属性, 给一个未定义的属性赋值时,此方法会被触发,传递的参数是被设置的属性名和值。 ```php <?php class OOP { public function __set($name, $value) { echo 'get key: '. $name .' value : '.$value; } } $oop = new OOP(); $oop->name = 'shiwenyuan'; // output:get key: name value : shiwenyuan ``` # toString 是在直接输出对象引用时自动调用的, 前面我们讲过对象引用是一个指针,比如 说:`$p=new Person()`中,$p就是一个引用,我们不能使用`echo`直接输出$p,这样会输出**Catchable fatal error: Object of class Person could not be converted to string**这样的错误,如果你在类里面定义了`__toString()`方法,在直接输出对象引用的时候,就不会产生错误,而是自动调用 了`__toString()`方法, 输出`__toString()`方法中返回的字符,所以`__toString()`方法一定要有个返回值(`return` 语句)。 ```php <?php // Declare a simple class class TestClass { public $foo; public function __construct($foo) { $this->foo = $foo; } //定义一个__toString方法,返加一个成员属性$foo public function __toString() { return $this->foo; } } $class = new TestClass('Hello'); //直接输出对象 echo $class; // output: Hello ```