合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
## 4-3 PHP魔术方法的实现 在设计模式中会使用到面向对象中的一些魔术方法。 魔术方法主要分为以下几类: * `__get` , `__set` // 操作对象的属性 * `__call` , `__callStatic` // 访问对象中的普通方法、静态方法 * `__toString` // 将对象输出为字符串使用 * `__invoke` // 把对象当做函数来使用 ### 1. 操作对象的属性 *D:\wamp\www\demo\oop\framework\Think\Object.php* ~~~ <?php namespace Think; class Object { protected $array = array(); public function __set($key, $value) { var_dump(__METHOD__); $this->array[$key] = $value; } public function __get($key) { var_dump(__METHOD__); return $this->array[$key]; } } ~~~ *D:\wamp\www\demo\oop\framework\index.php* ~~~ $obj = new Think\Object(); $obj->title = 'title'; echo $obj->title; ~~~ 输出结果: ~~~ string 'Think\Object::__set' (length=19) string 'Think\Object::__get' (length=19) title ~~~ 当给一个对象不存在的变量赋值时,自动调用 `__set()` 方法,读取一个不存在的对象的值时,自动调用 `__get()` 方法。 ### 2. 访问对象中的方法 *D:\wamp\www\demo\oop\framework\index.php* ~~~ $obj = new Think\Object(); $obj->demo('name', 'zhangsan'); ~~~ 访问对象中不存在的方法时,会提示: ~~~ Fatal error: Call to undefined method Think\Object::demo() ~~~ 该方法不存在。 *D:\wamp\www\demo\oop\framework\index.php* ~~~ $obj = new Think\Object(); echo $obj->demo('name', 'zhangsan'); echo $obj::demo('age', 100); ~~~ 接下来,我们在类中定义魔术方法:`__call()` , `__callStatic()` *D:\wamp\www\demo\oop\framework\Think\Object.php* ~~~ public function __call($func, $param) { var_dump($func, $param); return "魔术方法\n"; } static public function __callStatic($func, $param) { var_dump($func, $param); return "魔术方法\n"; } ~~~ 输出内容: ~~~ string 'demo' (length=4) array (size=2) 0 => string 'name' (length=4) 1 => string 'zhangsan' (length=8) 魔术方法 string 'demo' (length=4) array (size=2) 0 => string 'age' (length=3) 1 => int 100 魔术方法 ~~~ 访问对象中1个不存在的方法,自动执行魔术方法 `__call`,如果访问的是静态方法,自动执行魔术方法 `__callStatc` 。 ### 3. 把对象转化为字符串 定义一个魔术方法 `__toString()` ~~~ public function __toString() { return __CLASS__; } ~~~ ~~~ $obj = new Think\Object(); echo $obj; ~~~ 输出内容: ~~~ Think\Object ~~~ 对象本身是不能直接输出的,当输出一个对象时,对象会自定回调访问 `__toString()` 魔术方法。 ### 4. 把对象当做函数 定义一个魔术方法: `__invoke()` ~~~ public function __invoke($param) { var_dump($param); return "__invoke\n"; } ~~~ 当把一个对象当做函数一样使用,会自动调用魔术方法:`__invoke()` ~~~ $obj = new Think\Object(); echo $obj('zhangsan'); ~~~ 输出结果: ~~~ string 'zhangsan' (length=8) __invoke ~~~