<?phpnamespace longli;class Employee {
private $name;
public function __set($xproName, $value) {
echo '<p>Employee::__set is called $proName=='.$xproName.', $value=='.$value.'</p>';
$this->xproName = $value;
}
}
class CEO extends Employee {
function __construct($name="") {
echo '<h2>CEO::__construct begin!</h2>';
$this->name = $name;
echo '<h2>CEO::__construct end!</h2>';
}
}$boss = new CEO("Blus");
?>
上面的代码,__set()被莫名其妙执行了两次,请问这是为什么呢? 输出结果为:CEO::__construct begin!Employee::__set is called $proName==name, $value==BlusEmployee::__set is called $proName==xproName, $value==BlusCEO::__construct end!
private $name;
public function __set($xproName, $value) {
echo '<p>Employee::__set is called $proName=='.$xproName.', $value=='.$value.'</p>';
$this->xproName = $value;
}
}
class CEO extends Employee {
function __construct($name="") {
echo '<h2>CEO::__construct begin!</h2>';
$this->name = $name;
echo '<h2>CEO::__construct end!</h2>';
}
}$boss = new CEO("Blus");
?>
上面的代码,__set()被莫名其妙执行了两次,请问这是为什么呢? 输出结果为:CEO::__construct begin!Employee::__set is called $proName==name, $value==BlusEmployee::__set is called $proName==xproName, $value==BlusCEO::__construct end!
你赋值了两次当然就执行两次了。
在调用重载方法__set的时候,第二次给未定义的类成员 $xproName赋值: $this->xproName = $value; 调用一次。
我想你的本意是这样:
public function __set($xproName, $value) {
echo '<p>Employee::__set is called $proName=='.$xproName.', $value=='.$value.'</p>';
// 这个 $xproName是一个变量,内容是变量名。 详见手册中 可变变量
$this->$xproName = $value;
}
http://www.php.net/manual/zh/language.variables.variable.php
echo '<p>Employee::__set is called $proName=='.$xproName.', $value=='.$value.'</p>';
// 我以为是要在这里设置隐藏属性的值(添加一个“隐藏的属性”)
// 但事实上,这里只是设置了一个名字为'$xproName' 的隐藏属性,
// 但是,这里怎么没有进入“死循环”呢?
$this->xproName = $value;
}
//__get()方法用来获取私有属性
private function __get($property_name)
{
if(isset($this->$property_name))
{
return($this->$property_name);
}else
{
return(NULL);
}
}
//__set()方法用来设置私有属性
private function__set($property_name,$value)
{
$this->$property_name=$value;
}
我觉得用__set()来实现的封装是过分的封装,为什么要在类外部修改一个隐藏的属性?为什么不设为公有?至于说 事实上,为了“添加一个隐藏属性”
添加一个隐藏的属性?你的程序需要的属性名难道不是固定的吗?你应该先声明该隐藏属性。
与 Access 和 Assign 一样,如果仅仅将 __get 和 __set 作用于对象属性的存取,就大有画蛇添足的嫌疑
__get 和 __set 在对象中的作用是在存取属性的同时隐式的之行一些方法,而无需显式的调用方法