5
class Dog {

    protected $bark = 'woof!';

    public function __get($key) {
        if (isset($this->$key)) {
            return $this->$key;
        }
    }
    public function __set($key, $val) {
        if (isset($this->$key)) {
             $this->$key = $val;
        }
    }
 }

使用这些功能有什么意义。

如果我可以使用

$dog = new Dog();
$dog->bark = 'woofy';
echo $dog->bark;

为什么我会费心将“吠叫”声明为protected?这种情况下的__get()__set()方法是否有效地公开了“吠叫”?

4

3 回答 3

4

在这种情况下,它们确实$this->bark有效地公开了,因为它们只是直接设置和检索值。但是,通过使用 getter 方法,您可以在设置时做更多工作,例如验证其内容或修改类的其他内部属性。

于 2011-07-19T02:22:47.870 回答
3

不一定必须与对象的属性一起使用。

这就是使他们强大的原因。

例子

class View extends Framework {

    public function __get($key) {
        
        if (array_key_exists($key, $this->registry)) {
            return trim($this->registry[$key]);
        }

    }
}

基本上,我试图证明它们不必仅仅用作对象属性的 getter 和 setter。

于 2011-07-19T02:20:23.677 回答
2

您通常永远不会离开这些__get,并且__set完全按照您离开的方式离开。

这些方法可能有用的方法有很多。以下是您可以使用这些方法执行的几个示例。

您可以将属性设为只读:

protected $bark = 'woof!';
protected $foo = 'bar';

public function __get($key) {
    if (isset($this->$key)) {
        return $this->$key;
    }
}
public function __set($key, $val) {
    if ($key=="foo") {
         $this->$key = $val; //bark cannot be changed from outside the class
    }
}

您可以在实际获取或设置数据之前对您拥有的数据进行处理:

// ...
public $timestamp;

public function __set($var, $val)
{
    if($var == "date")
    {
        $this->timestamp = strtotime($val);
    }
}

public function __get($var)
{
    if($var == date)
    {
        return date("jS F Y", $this->timestamp);
    }
}

您可以使用的另一个简单示例__set可能是更新数据库中的一行。因此,您要更改的内容不一定在类内部,而是使用类来简化更改/接收的方式。

于 2011-07-19T02:30:55.300 回答