PHP面向对象深入理解之三(类中的魔术方法)

xiaoxiao2021-02-28  94

通常情况下,不建议使用魔术方法,因为会增加opcode,影响程序的性能。

1. __toString

通常你使用print 打印一个类的时候,你会发现打印出来的类似于 Object id#1 的id句柄,如果我们不想得到这样的句柄,那我们可以改写__toString 方法 class A { private $name = 'A class'; public function __construct($name) { $this->name = $name; } public function __toString() { return $this->name; } } $a = new A('a'); $b = new A('b'); print $a; print $b;

2. __set 和__get

__get方法是某个成员变量不能存在的时候,访问会报错,可以通过设置__get,避免报错,通常与__set配合使用 __set则是无此变量时,可以设置默认加入方式,让__get能访问到 class A { private $data = null; public function __get($name) { return isset($this->data[$name])?$this->data[$name]:''; } public function __set($name,$value) { $this->data[$name] = $value; } } $a = new A(); $a->age = 13; print $a->age;

3. __sleep 和 __wakeup

__sleep 用于对象serialize序列化的时候,准备序列化需要的资源   它必须返回的是当前类的成员变量的名字组成的数组 __wakeup 则相反,在对象unserilize反序列化的时候 会优先执行的操作 class A { public $name = 'zhansan'; public function __sleep() { return array('name'); } public function __wakeup() { echo 'bbb'; } public function geta() { echo 'a is running '; } } $a = new A(); $astr = serialize($a); //注意一个对象被序列化的时候 他的方法和功能依然被保留 print $astr; //只是暴露给外界的很少 $newa = unserialize($a); //反序列化的时候 就被重新激活了会优先调用__wakeup $newa->geta(); //不信,你看 仍然能调用 打印结果:O:1:"A":1:{s:4:"name";s:7:"zhansan";}bbba is running

4.__invoke

当尝试以调用函数的方式,调用一个对象的时候,__invoke就被激活了 class A { public function __invoke($argvs) { var_dump($argvs); } } $a = new A(); $a('obj is called'); 打印: string(13) "obj is called"

5.  __call 和 __callStatic(5.3.0以后)

当对象调用一个不存在的方法时,会自动触发__call方法 而调用一个不存在的静态方法时,会自动触发__callStatic <?php class A { public function __call($funcname,$argvs) { echo 'call:'; var_dump($funcname,$argvs); } public static function __callStatic($funcname,$argvs) { echo 'call static:'; var_dump($funcname,$argvs); } } $a = new A(); A::runaaa('abc'); $a->getbbb('111'); 打印结果: call static:string(6) "runaaa" array(1) {   [0]=>   string(3) "abc" } call:string(6) "getbbb" array(1) {   [0]=>   string(3) "111" }

6. __isset 和 __unset

对象的不存在属性或不可访问属性调用 isset()和empty() 方法 __isset 会被触发 unset() 则触发 __unset class A { private $data = array(); public function __get($name) { return $this->data[$name]; } public function __set($name,$value) { $this->data[$name] = $value ; } public function __isset($name) { echo 'isset:'; return isset($this->data[$name]); } public function __unset($name) { echo 'unset:' unset($this->data[$name]); } } $a = new A(); $a->name='aa'; var_dump(isset($a->name)); unset($a->name); var_dump(isset($a->name)); 打印结果: isset:bool(true) unset:isset:bool(false)

7. __clone

当调用clone 操作符来复制一个新对象时,会触发__clone 方法 如果,对象的某些属性是使用的引用的方式,新对象仍然会因为旧对象的改变而改变; class A { public $name = 'lisi'; public $obj = null; public function __clone() { echo 'clone is called'; $this->name = 'lisi'; //这里做一些初始化操作 $this->obj = clone $this->obj; //做深度拷贝 } } $a = new A(); $a->name = 'zhao'; $b = clone $a; var_dump($b->name); var_dump($a->name); $c= new A(); $a->obj = $c; 打印: clone is calledstring(4) "lisi"

string(4) "zhao"

转载请注明原文地址: https://www.6miu.com/read-31680.html

最新回复(0)