自动Getter / Setter功能

时间:2011-11-02 16:06:49

标签: php symfony1 doctrine

我正在查看Doctrine 2和Symfony文档来创建模型类。有几个代码片段,其中在类中使用了getProperty和setProperty,当值直接赋值给属性时,它们会以某种方式自动使用。这与典型的get / set魔术方法不同,我遇到的示例代码没有实现任何自定义魔术方法,所以我相信这是由Doctrine在某处处理的。

从我读过的内容来看,Doctrine实现了访问器和mutator。也许我在下载Pear时错过了一个软件包,或者我的脚本中没有包含一些内容。

例如:

class User {

    public $name;
    public function getName()
    {
        // Do stuff
    }
}

$user = new User();
$foo = $user->name; // getName is called

注意:我正在寻找一个特定于学说的解决方案。我知道这可以通过PHP进行,但我想使用Doctrine的本机函数。

编辑:更新以阐明这与典型的获取/设置魔术方法的区别,并注意。

2 个答案:

答案 0 :(得分:6)

class User {
    private $name;
    public function __get($property) {
        $methodName = "get".ucfirst($property);
        if (method_exists($this, $methodName)) {
           return call_user_func(array($this, $methodName));
        } elseif (isset($this->{$property})) {
            return $this->{$property};
        }
        return null;
    }
    public function __set($property, $value) {
        $methodName = "set".ucfirst($property);
        if (method_exists($this, $methodName)) {
            call_user_func_array(array($this,$methodName), array($value));
        } else {
            $this->{$property} = $value;
        }
    }
    public function getName() {
        return "My name is ".$this->name;
    }
}

$user = new User();
$user->name = "Foo";
$bar = $user->name;
echo $bar; // "My name is Foo"

如果有方法getSomethingsetSomething,则会在直接访问属性时调用它。

正如我在this documentation page中所读到的那样,正是上面的代码与Doctrine所做的完全相同。但它调用方法_set('fieldName', 'value')

答案 1 :(得分:2)

如果$name被声明为public,那么这行代码为:

$foo = $user->name;

实际上正在访问$name字段,实际上并未调用getName函数。

您可以使用PHP的魔术__get__set方法自动提供访问器和更改器,如下所示:

class User {
    private $name;
    public function __get($property) {
       //check first to make sure that $property exists 
       return $this->$property;
    }
    public function __set($property, $value) {
        //check first to make sure that $property exists
        $this->$property = $value;
    }
}

$user = new User();
$user->name = "Foo";
$bar = $user->name;
echo $bar; //"Foo"

您可以找到有关PHP的魔法here的更多信息。

更新:这就是我认为Doctrine正在做的事情:

class User {
    private $name;
    public function __get($property) {
       $propertyTitleCase = mb_convert_case($property, MB_CASE_TITLE);
       $method = "get{$propertyTitleCase}";
       if(method_exists($this, $method))
       {
          return $this->$method();
       }
       else {
          return $this->$property;
       }
    }

    public function getName() {
        //Do Stuff
    }
}