🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## 魔术方法 ### `__construct` 构造方法 * 构造方法 ``` function __construct([参数列表]) { 方法体 //通常用来对成员属性进行初始化赋值 } ``` **** ### `__destruct` 析构方法 * 析构方法 ``` function __destruct() { //方法体 } ``` **** ### `__call()` 对象中调用一个不可访问方法时调用 > * `string $function_name, array $arguments` > * 第一个参数 `$function_name` 会自动接收不存在的方法名, > * 第二个 `$arguments` 则以数组的方式接收不存在方法的多个参数。 ``` /** * 声明此方法用来处理调用对象中不存在的方法 */ function __call(string $function_name, array $arguments) { echo "你所调用的函数:" . $function_name. "(参数:" ; // 输出调用不存在的方法名 print_r($arguments); // 输出调用不存在的方法时的参数列表 echo ")不存在!<br>\n"; // 结束换行 } ``` **** ### `__callStatic()` 用静态方式中调用一个不可访问方法时调用 > * 同 `__call` 的参数 一样 ``` /** * 声明此方法用来处理调用对象中不存在的方法 */ public static function __callStatic($function_name, $arguments) { echo "你所调用的静态方法:" . $function_name. "(参数:" ; // 输出调用不存在的方法名 print_r($arguments); // 输出调用不存在的方法时的参数列表 echo ")不存在!<br>\n"; // 结束换行 } ``` **** ### `__get()` 获得一个类的成员变量时调用 > * `$propertyName`属性名作为参数传入并处理 > * 通过它可以在对象的外部获取私有成员属性的值 ``` /** * 在类中添加__get()方法,在直接获取属性值时自动调用一次,以属性名作为参数传入并处理 * @param $propertyName * * @return int */ public function __get($propertyName) { return $this->$propertyName; } ``` **** ### `__set()` 设置一个类的成员变量时调用 >* `$property, $value` 参数名和值 ``` /** * 声明魔术方法需要两个参数,真接为私有属性赋值时自动调用,并可以屏蔽一些非法赋值 * @param $property * @param $value */ public function __set($property, $value) { $this->$property = $value; } ``` **** ### `__isset()` 当对不可访问属性调用`isset()`或`empty()`时调用 > * `$content` 类参数 ``` /** * @param $content * * @return bool */ public function __isset($content) { echo "当在类外部使用isset()函数测定私有成员{$content}时,自动调用<br>"; echo isset($this->$content); } ``` **** ### `__unset()` 当对不可访问属性调用`unset()`时被调用。 > * `$content` 类参数 ``` /** * @param $content * * @return bool */ public function __unset($content) { echo "当在类外部使用unset()函数来删除私有成员时自动调用的<br>"; echo isset($this->$content); } ``` **** ### `__sleep()` 执行`serialize()`时,先会调用这个函数 > * `serialize()` 函数会检查类中是否存在一个魔术方法 `__sleep()` > * 如果存在,则该方法会优先被调用,然后才执行序列化操作。 > * 此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。 > * 如果该方法未返回任何内容,则 `NULL` 被序列化,并产生一个 `E_NOTICE` 级别的错误。 > * `__sleep()` 不能返回父类的私有成员的名字。这样做会产生一个 `E_NOTICE` 级别的错误。可以用 `Serializable` 接口来替代。 > * 作用: > `__sleep()` 方法常用于提交未提交的数据,或类似的清理操作。同时,如果有一些很大的对象,但不需要全部保存,这个功能就很好用。 ``` /** * @return array */ public function __sleep() { echo "当在类外部使用serialize()时会调用这里的__sleep()方法<br>"; $this->name = base64_encode($this->name); return array('name', 'age'); // 这里必须返回一个数值,里边的元素表示返回的属性名称 } ``` **** ### `__wakeup()` 执行`unserialize()`时,先会调用这个函数 > * `__wakeup()` 经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。 ``` /** * __wakeup */ public function __wakeup() { echo "当在类外部使用unserialize()时会调用这里的__wakeup()方法<br>"; $this->name = 2; $this->sex = '男'; // 这里不需要返回数组 } ``` **** ### `__toString()` 类被当成字符串时的回应方法 >* PHP 5.2.0 之前,`__toString()` 方法只有在直接使用于 `echo`或 `print` 时才能生效。 >* PHP 5.2.0 之后,则可以在任何字符串环境生效(例如通过 `printf()`,使用 `%s` 修饰符),但不能用于非字符串环境(如使用 `%d` 修饰符)。 >* 自 PHP 5.2.0 起,如果将一个未定义 `__toString()` 方法的对象转换为字符串,会产生 `E_RECOVERABLE_ERROR` 级别的错误。 ``` public function __toString() { return 'go go go'; } ``` **** ### `__invoke()` 调用函数的方式调用一个对象时的回应方法 ``` public function __invoke() { echo '这可是一个对象哦'; } $person = new Person('小明'); // 初始赋值 $person(); ``` **** ### `__set_state()` 调用var_export()导出类时,此静态方法会被调用。 > * 本方法的唯一参数是一个数组,其中包含按 array('property' => value, ...) 格式排列的类属性 ``` public static function __set_state($an_array) { $a = new Person(); $a->name = $an_array['name']; return $a; } ``` **** ### `__clone()` 当对象复制完成时调用 ``` public function __clone() { echo __METHOD__."你正在克隆对象<br>"; } $person = new Person('小明'); // 初始赋值 $person2 = clone $person; ``` **** ### `__autoload()` 尝试加载未定义的类 > * `spl_autoload_register` 也可通过该函数注册 自定义 加载函数 > * 魔术函数 ,跟普通函数调用方式一样,不写在类里面 ``` /** * 文件autoload_demo.php * */ function __autoload($className) { $filePath = "project/class/{$className}.php"; if (is_readable($filePath)) { require($filePath); } } ``` **** ### `__debugInfo()` 打印所需调试信息 > * 该方法在PHP 5.6.0及其以上版本才可以用 ``` /** * @return array */ public function __debugInfo() { return [ 'propSquared' => $this->prop ** 2, ]; } ```