PHP魔术方法
php
php
字数统计: 1.6k(字)
阅读时长: 7(分)
前言
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __serialize(), __unserialize(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo() 等方法在 PHP 中被称为魔术方法(Magic methods)。在命名自己的类方法时不能使用这些方法名,除非是想使用其魔术功能。
参考文献
魔术方法官方文档:https://www.php.net/manual/zh/language.oop5.magic.php
演示
__construct:构造方法
__destruct:析构函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?php class Magic { public function __construct() { echo '对象被实例化 new 的时候调用此方法' . PHP_EOL; }
public function __destruct() { echo '对象删除或者销毁时被调用' . PHP_EOL; } } new Magic;
|
__call(),在对象中调用一个不可访问方法时调用
__callStatic(),用静态方式中调用一个不可访问方法时调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <?php class Magic { public function __call($funName, $arguments) { echo "你所调用的函数:" . $funName . "(参数:"; print_r($arguments); echo ")不存在!\n" . PHP_EOL; }
public static function __callStatic($funName, $arguments) { echo "你所调用的静态方法:" . $funName . "(参数:"; print_r($arguments); echo ")不存在!\n" . PHP_EOL; } } $magic = new Magic; var_dump($magic->testCall('names')); var_dump(Magic::testCall('names'));
|
__get(),获得一个类的成员私有的变量时调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php class Magic { private $value = 100;
public function __get($propertyName) { return $this->$propertyName = 200; } } $magic = new Magic; echo $magic->value;
|
__set(),设置一个类的成员私有的变量时调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <?php class Magic { private $value = 100;
public function __set($property, $value){ $this->$property = $value; }
public function run(){ return $this->value; } } $magic = new Magic; $magic->value = 666; echo $magic->run();
|
__isset(),当对不可访问属性调用isset()或empty()时调用
__unset(),当对不可访问属性调用unset()时被调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <?php class Magic { public $name = '张三'; private $area = '北京';
public function __isset($content) { echo "当在类外部使用isset()函数测定私有成员{$content}时,自动调用<br>"; echo isset($this->$content) . "<br>"; }
public function __unset($content) { echo "当在类外部使用unset()函数来删除私有成员时自动调用的<br>"; echo isset($this->$content) . "<br>"; } } $magic = new Magic; echo isset($magic->name), "<br>"; echo isset($magic->area), "<br>";
unset($magic->name); unset($magic->area);
|
__sleep(),执行serialize()时,先会调用这个函数
__wakeup(),执行unserialize()时,先会调用这个函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?php class Magic { public $name = '张三'; private $area = '北京';
public function __sleep(){ echo "当在类外部使用serialize()时会调用这里的__sleep()方法<br>"; $this->name = base64_encode($this->name); return array('name', 'age'); }
public function __wakeup(){ echo "当在类外部使用unserialize()时会调用这里的__wakeup()方法<br>"; $this->name = '李四'; $this->area = '上海'; } } $magic = new Magic; var_dump(serialize($magic));
var_dump(unserialize(serialize($magic)));
|
__toString(),类被当成字符串时的回应方法
1 2 3 4 5 6 7 8 9 10 11
| <?php class Magic{ public function __toString(){ return '我是类呀,不是字符串'; } } $magic = new Magic; echo $magic;
|
__invoke(),调用函数的方式调用一个对象时的回应方法
1 2 3 4 5 6 7 8 9 10 11
| <?php class Magic{ public function __invoke(){ echo '这可是一个对象哦'; } } $magic = new Magic; $magic();
|
__set_state(),调用var_export()导出类时,此静态方法会被调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?php class Magic{ public $name; public $age;
public function __construct($name = "", $age = 25){ $this->name = $name; $this->age = $age; }
public static function __set_state($an_array){ $a = new Magic(); $a->name = $an_array['name']; return $a; } } $person = new magic('小明'); $person->name = '小红'; var_export($person);
|
__clone(),当对象复制完成时调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <?php class Magic{ public $name = '张三'; public function __clone() { echo __METHOD__ . "你正在克隆对象<br>"; } } $magic = new magic(); $magic2 = clone $magic;
$magic->name = '李四'; echo $magic->name . "<br>"; echo $magic2->name . "<br>";
$magic2->name = '王五'; echo $magic->name . "<br>"; echo $magic2->name . "<br>";
|
__autoload(),尝试加载未定义的类
警告 本函数已自 PHP 7.2.0 起被废弃,并自 PHP 8.0.0 起被移除。 强烈建议不要依赖本函数。spl_autoload_register — 注册给定的函数作为 __autoload 的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?php function __autoload($className) { $filePath = "project/class/{$className}.php"; die($filePath); if (is_readable($filePath)) { require($filePath); } } $a = new TestClass();
|
__debugInfo(),打印所需调试信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?php class Magic{ private $prop;
public function __construct($val){ $this->prop = $val; }
public function __debugInfo(){ return [ 'propSquared' => $this->prop ** 2, ]; } } var_dump(new Magic(666));
|