<?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!

解决方案 »

  1.   

    __set( $property, $value ) : 给一个未定义的属性赋值时调用 
    你赋值了两次当然就执行两次了。
      

  2.   

    第一次给未定义的类成员$name赋值: $this->name = $name; 调用一次
    在调用重载方法__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
      

  3.   

    好吧,我小白了。我本以为要自己写代码在__set()方法里完成“不可见属性”的设置,所以写了这个函数: public function __set($xproName, $value) {
            echo '<p>Employee::__set is called $proName=='.$xproName.', $value=='.$value.'</p>';
            
            // 我以为是要在这里设置隐藏属性的值(添加一个“隐藏的属性”)
            // 但事实上,这里只是设置了一个名字为'$xproName' 的隐藏属性,
            // 但是,这里怎么没有进入“死循环”呢?
            $this->xproName = $value;
     }
      

  4.   

    预定义了两个函数“__get()”和“__set()”来获取和赋值其属性,以及检查属性的“__isset()”
    //__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;
    }
      

  5.   

    你仍然没弄清楚__set()的作用,当你为类成员属性$xproName赋值后,它已经不再是未定义了。所以不具备死循环的条件。
    我觉得用__set()来实现的封装是过分的封装,为什么要在类外部修改一个隐藏的属性?为什么不设为公有?至于说 事实上,为了“添加一个隐藏属性”
    添加一个隐藏的属性?你的程序需要的属性名难道不是固定的吗?你应该先声明该隐藏属性。
      

  6.   

    所用面向对象的语言中都对对象的每个属性设有 Access 和  Assign 方法,以便开发者灵活的控制对象的行为。由于 php 不是面向对象的语言,所以虽然粗糙的提供了 __get 和 __set 方法,但与 Access 和  Assign 相比还是有很大差距的
    与 Access 和  Assign 一样,如果仅仅将 __get 和 __set 作用于对象属性的存取,就大有画蛇添足的嫌疑
     __get 和 __set 在对象中的作用是在存取属性的同时隐式的之行一些方法,而无需显式的调用方法
      

  7.   

    $this->$xproName = $value;
      

  8.   

    一个重要原因还是为了兼容....php4