在 php 的面向对象编程中,当一个成员属性被定义为 private 或 protected 时,如果我们试图在外面直接调用它或者给属性赋值都会出现“不能访问某个私有属性或受保护属性”的错误。面对这样的需求,PHP 提供了 __get() 和 __set() 的魔术方法。其中 __get() 可以访问非公有属性,__set() 可以给非公有属性赋值。
1、__get()
方法必须有一个参数
public function __get($name) // 必有一个参数
案例
class Person
{
private $name;
private $age;
function __construct($name="", $age=1)
{
$this->name = $name;
$this->age = $age;
}
/**
* 在类中添加__get()方法,在直接获取非公有属性时自动调用一次,以属性名作为参数传入并处理
* @param $name 访问的属性名
*
* @return int
*/
public function __get($name)
{
if ($name == "age") {
if ($this->age > 30) {
return $this->age - 10;
} else {
return $this->$name;
}
} else {
return $this->$name;
}
}
}
$person = new Person("kevin", 60); // 通过Person类实例化的对象,并通过构造方法为属性赋初值
echo "姓名:" . $person->name . "\r\n"; // kevin, 直接访问私有属性name,自动调用了__get()方法可以间接获取
echo "年龄:" . $person->age . "\r\n"; // 50, 自动调用了__get()方法,根据对象本身的情况会返回不同的值
echo "\r\n";
2、__set()
方法必须有两个参数,参数一:属性名,参数二:属性值
public function __set($name, $value)
案例
class Person
{
private $name;
private $age;
function __construct($name="", $age=1)
{
$this->name = $name;
$this->age = $age;
}
/**
* 在类中添加 __get()方法,在直接获取非公有属性时自动调用一次,以属性名作为参数传入并处理
* @param $propertyName
*
* @return int
*/
public function __get($propertyName)
{
if ($propertyName == "age") {
if ($this->age > 30) {
return $this->age - 10;
} else {
return $this->$propertyName;
}
} else {
return $this->$propertyName;
}
}
/**
* 在类中添加 __set()方法,给对象的非公有属性赋值
* @param $name 要赋值的属性
* @param $value
*/
public function __set($name, $value)
{
$this->$name = $value;
}
}
$person = new Person("kevin", 60); // 通过Person类实例化的对象,并通过构造方法为属性赋初值
$person->name = 'loedan';
$person->age = 20;
echo "姓名:" . $person->name . "\r\n"; // loedan, 通过 __set() 给属性赋值
echo "年龄:" . $person->age . "\r\n"; // 20, 通过 __set() 给属性赋值
echo "\r\n";