php中的魔术方法

php中内置了不少被赋予魔术性质的「魔术方法」,魔术方法以双下划线开头「__」,在类中使用,在特定的条件下自动在程序中被调用,由于具有在特定条件下自动被调用的特性,使得编程过程得以简化。

在PHP中魔术方法有:__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone(), __autoload()

1. __construct() 和 __destruct()

__construct()和__destruct()分别称为构造函数与析构函数,在对象被创建和销毁的时候由系统自动调用,跟其他编程语言中构造函数与析构函数一样,也是在面向对象编程中使用最频繁的。

构造函数主要完成对象在创建时候的初始化工作,一般用于初始化对象的成员,在PHP中,子类使用父类的构造函数必须使用parent::__construct()显示调用,不支持隐式自动调用。

对应的析构函数是对象在被系统销毁时自动调用。包括对象被显式销毁或者该对象的所用引用都被删除。跟构造函数一样,子类析构函数使用父类析构函数同样使用parent::__destruct()显示调用。

construct

2. __call()和__callStatic()

当调用对象不可访问的方法或者没有的方法时自动调用__call()魔术方法。该魔术方法有两个参数,第一个是调用的方法名称,第二个参数是枚举数组参数列表。用静态方式调用不可访问的方法或者没有的方法时自动调用__callStatic()魔术方法。

测试后发现对于存在但不可访问的方法并不能通过__call来调用,调用顺序为,先在自己类中寻找方法,如没找到,向父类中寻找,如果在父类中找到则调用父类中方法,如果没有找到而本类中有__call方法则执行__call魔术方法。

call_01

该魔术方法另外一个比较重要的用途就是实现重载,在PHP手册中这两个魔术方法介绍的标题也是方法重载。

call_02

3. __get() 和 __set()

当读取不可访问或者未定义的属性时,访问__get()方法。当设置不可访问或者未定义的属性时,访问__set()方法。

4. __isset()和__unset()

当在一个未定义或者不可访问的属性中调用isset()函数时访问__isset()方法。当在一个未定义或者不可访问的属性中调用unset()函数时访问__unset()方法。

 5. __sleep()和__wakeup()

这两个魔术方法在进行序列化的时候使用,通过序列化可以将任何类型数据转化为字符串格式,我们可以通过序列化对象,将其转化为字符串格式保存起来。在进行序列化的时候,检查类中是否有__sleep()魔术方法,如果有就调用该方法。在进行反序列化的时候会检查类中是否有__wakeup()魔术方法,如果有就调用该方法。

通常在__sleep()方法中处理不需要序列化的部分内容或者做一些对象的清理工作,而在__wakeup()方法中进行一些初始化操作。这两个方法是配合序列化和反序列化使用的。

6. __toString()

将对象当初字符串在程序中使用时,会自动调用该方法,例如我们echo一个对象时将调用这个方法,如果不存在该方法,则出现错误。

7. __invoke()

当尝试以调用函数的方式调用一个对象时,__invoke 方法会被自动调用。

8. __set_state()

当调用var_export()导出类时,该方法被自动调用。

9. __clone()

复制对象时使用clone方法,在复制完成时,如果定义了__clone方法,则会自动被调用,可用于修改新复制对象的属性或进行初始化工作。

10. __autoload()

使用这个方法可以进行类的自动加载,比如我们可以在该方法中完成包含文件的自动加载。

autoload