【问题标题】:PHP __get __set methodsPHP __get __set 方法
【发布时间】:2011-07-19 02:18:15
【问题描述】:
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() 方法是否有效地公开了“吠叫”?
【问题讨论】:
标签:
php
setter
getter
magic-methods
【解决方案1】:
在这种情况下,它们确实使$this->bark 有效地公开,因为它们只是直接设置和检索值。但是,通过使用 getter 方法,您可以在设置时做更多的工作,例如验证其内容或修改类的其他内部属性。
【解决方案2】:
不一定必须与对象的属性一起使用。
这就是它们强大的原因。
示例
class View extends Framework {
public function __get($key) {
if (array_key_exists($key, $this->registry)) {
return trim($this->registry[$key]);
}
}
}
基本上,我试图证明它们不必仅用作对象属性的 getter 和 setter。
【解决方案3】:
您通常不会完全按照您离开时的状态离开 __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 执行的另一个简单示例可能是更新数据库中的一行。因此,您要更改的内容不一定在类内部,而是使用类来简化更改/接收的方式。