# 魔术方法(Magic Methods)

* \_\_construct()  构造方法,类实例化的时候执行
* \_\_destruct()  析构函数,某个对象所有引用都被删除或者当前对象显示销毁的时候执行
* \_\_call()  调用类中一个不存在的方法的时候执行
* \_\_callStatic()  调用不存在的静态方法时,执行
* \_\_get()  调用不在的数组时执行
* \_\_set()  设置对象中不存在的属性时执行
* \_\_isset()  判断一个对象属性是否存在时执行
* \_\_unset() 销毁一个对象属性时执行
* \_\_sleep()  序列化一个对象前执行
* \_\_wakeup() 反序列化一个对象前执行
* \_\_toString() 把对象当成字符串输出时执行,返回一个字符串
* \_\_invoke()  把对象以函数的形式调用的时候执行
* \_\_set\_state()   5.1.0时启用,调用var\_export函数前执行
* \_\_clone()  克隆一个的对象的时候调用

示例:

```php
class Test {

    function __call($function_name, $args)
    {
        echo "你所调用的方法：$function_name(参数：<br />";
        var_dump($args);
        echo ")不存在！";
    }

    function __callstatic($function_name, $args)
    {
        echo "你所调用的静态方法：$function_name(参数：<br />";
        var_dump($args);
        echo ")不存在！";
    }
}

$obj = new Test();
$obj->test();
$obj::test();
```

示例:

注意:经过测试,两个方法不能同时存在,只能有一个被运行(php7下测试运行)

```php
class Test {

    function __sleep()
    {
      echo '执行了serialize()函数';
    }


    function __wakeup()
    {
        echo '执行了unserialize()函数';
    }
}

$obj = new Test();
$serializeObj = serialize($obj);
$unserializeObj = unserialize($serializeObj);
```

示例:

```php
class Test {

    function __invoke()
    {
        echo '把对象当成函数调用了';
    }
}

$obj = new Test();
$obj();
```

示例:

```php
<?php

class Test {

    function __toString()
    {
        return '把对象当成字符串了';
    }
}

$obj = new Test();
echo $obj;
```

实例

```php
class Test{
    public $a;
    static function __set_state($array) {//必须是静态方法,参数是一个数组
        echo '调用了var_export函数';
        $tmp = new Test();
        $tmp->a = 'abc';//直接赋值
        return $tmp;//必须返回一个对象，可以是其他类的对象
    }

}
$test = new Test();
eval('$b = '.var_export($test,true).';');
var_dump($b);
```

## 资料

[php---魔术方法（\_\_tostring()，\_\_set\_state()）](https://my.oschina.net/zhangdapeng89/blog/40296)

[中年大叔的PHP学习之旅——魔术方法\_\_sleep和\_\_wakeup](http://blog.sina.com.cn/s/blog_758ddcb90100yk05.html)
