PHP 魔术方法 - __get()
当我们试图访问 PHP 对象中的不存在的属性或者私有的属性时,程序会抛出异常并且停止执行,例如下面的代码
<?php class Person { private $name; private $age; function __construct($name="", $age=1) { $this->name = $name; $this->age = $age; } } $person = new Person("Yufei", 30); // 使用参数 "Yufei" 和 30 初始化一个对象 echo "Name:" . $person->name . "\n"; echo "Sex: " . $person->sex . "\n"; // 因为程序终止执行,所以这一条语句不会执行
运行结果如下
[yufei@localhost php]$ php demo.php Fatal error: Uncaught Error: Cannot access private property Person::$name in /Users/yufei/php/demo.php:15 Stack trace: #0 {main} thrown in /Users/yufei/php/demo.php on line 15
出现这种异常是我们不想看到的,一种解决办法就是给私有的变量定义一个公开的访问方法。但如果是一个不存在的变量,就没办法定义一个公开的方法了。
没有其它办法了吗?
答案是显而易见的,因为我们的标题就是 __get()
魔术方法啊
__get()
魔术方法
当一个类定义了一个 __get()
魔术方法后,我们就可以获取该类的实例的私有属性或不存在的属性而不犯错,这里所说的获取,是指获取其值。
该方法的原型如下
public mixed function __get( string $propertyName) { // 一些代码 }
该方法只有一个参数,就是要获取的属性名称,且该函数可以返回任意数据类型,且必须有返回值。
范例
下面的方法,我们为 Person
定义了魔术方法 __get()
,从而解决上面出现的异常问题
<?php class Person { private $name; private $age; function __construct($name="", $age=1) { $this->name = $name; $this->age = $age; } public function __get($propertyName) { if ($propertyName == "age") { if ($this->age > 30) { return $this->age - 10; } else { return $this->$propertyName; } } else { return $this->$propertyName; } } } $person = new Person("Yufei", 30); // 使用参数 "Yufei" 和 30 初始化一个对象 echo "Name:" . $person->name . "\n"; // 当访问不可访问的属性时,会自动调用 __get() 方法 echo "Age:" . $person->age . "\n"; // 返回不一样的值 echo "Sex: " . $person->sex . "\n"; // 当访问不存在的属性时
运行结果如下
[yufei@localhost php]$ php demo.php Name:Yufei Age:30 Sex:
可以看到,当我们定义了 __get()
方法,即使属性不存在,也会返回一个 NULL 值
类的实例内部访问不存在的属性返回 NULL
这里有一个知识点,就是类的实例内部访问一个不能存在的属性,会返回 NULL
值,可以看如下的代码
<?php class Person { private $name; private $age; function say() { var_dump($this->sex); } } $person = new Person("Yufei", 30); // 使用参数 "Yufei" 和 30 初始化一个对象 $person->say();
运行结果如下
[yufei@localhost php]$ php demo.php NULL