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

来源:互联网 发布:淘宝神笔模板 编辑:程序博客网 时间:2024/06/11 04:05

通常情况下,不建议使用魔术方法,因为会增加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



<?phpclass 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"






原创粉丝点击