PHP 魔术方法 - __set()
在 PHP 魔术方法 - __get() 章节中,我们学习了如何访类实例的不存在的或私有的属性。那么,如果们要对这些属性进行赋值,或者改变它们的值,又要怎么做呢?
我们先来看看默认情况下会不会也报错
<?php class Person { private $name; private $age; function __construct($name="", $age=1) { $this->name = $name; $this->age = $age; } } $person = new Person("Yufei", 30); // 无参数创建实例 $person->name = "Yufei"; $person->sex = "Male"; 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:16 Stack trace: #0 {main} thrown in /Users/yufei/php/demo.php on line 16
看出错的结果在 16 行,也就是 $person->name = "Yufei";
这说明什么 ?
说明 「 给类实例的不存在的或私有的属性赋值,同样会抛出异常 」
同样的,解决办法也很简单,就是给类定义一个 __set()
魔术方法
__set()
魔术方法
魔术方法 __set()
用来给类的实例的不存在的属性或不可访问的属性赋值。
该方法的原型如下
public function __set($property, $value) { // 一些代码 }
该方法有两个参数,第一个参数 $property
是不存在或不可访问的实例的属性,第二个参数 $value
是实际要赋的值。
该方法可以有返回值,也可以没有返回值,完全由开发者自己决定
范例
为了修复一开始的异常,我们为 Person
类定义一个 __set()
方法
<?php class Person { private $name; private $age; public function __construct($name="", $age=25) { $this->name = $name; $this->age = $age; } public function __set($property, $value) { if ($property=="age") { if ($value > 150 || $value < 0) { return; } } $this->$property = $value; } public function say(){ echo "我的名字是: ".$this->name.", 我 ".$this->age." 岁了"; } } $Person=new Person("Yufei", 25); $Person->name = "Hero"; // 因为定义了 __set() 方法,所以我们可以给 $name 属性赋值 $person->age = 16; // 同样的,也可以给 $age 属性赋值 $person->age = 160; // 因为 160 不符合要求,所以 $age 还是保持原样 $person->say(); // 输出 print:My name is Lili, I'm 16 years old.
运行结果如下
[yufei@localhost php]$ php demo.php 我的名字是: Hero, 我 16 岁了
使用 __set()
给一个不存在的属性赋值时,该属性的访问级别问题
使用 __set()
给一个不存在的属性赋值时,该属性的访问级别是默认的 public
,请看下面的代码
<?php class Person { public function __set($property, $value) { $this->$property = $value; } } $person = new Person(); $person->name = 'Yufei'; echo $person->name, "\n";
输出结果如下
[yufei@localhost php]$ php demo.php Yufei