我最近研究了魔术方法__get
和__set
,想知道如何在类中实际设置和获取多个属性。
我知道它只适用于一个变量或数组,但我不确定是否要访问多个变量。
有人能向我解释吗?
class myMagic2 {
public $data;
public $name;
public $age;
public function __set($item, $value) {
$this->item = $value;
}
public function __get($item){
return $this->item;
}
}
是否有访问所有变量($data
、$name
、$age
)的方法?
当我在项目中工作时,我总是有以下方法:
public function __set($name, $value)
{
//see if there exists a extra setter method: setName()
$method = 'set' . ucfirst($name);
if(!method_exists($this, $method))
{
//if there is no setter, receive all public/protected vars and set the correct one if found
$vars = $this->vars;
if(array_search("_" . $name, $vars) !== FALSE)
$this->{"_" . $name} = $value;
} else
$this->$method($value); //call the setter with the value
}
public function __get($name)
{
//see if there is an extra getter method: getName()
$method = 'get' . ucfirst($name);
if(!method_exists($this, $method))
{
//if there is no getter, receive all public/protected vars and return the correct one if found
$vars = $this->vars;
if(array_search("_" . $name, $vars) !== FALSE)
return $this->{"_" . $name};
} else
return $this->$method(); //call the getter
return null;
}
public function getVars()
{
if(!$this->_vars)
{
$reflect = new ReflectionClass($this);
$this->_vars = array();
foreach($reflect->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED) as $var)
{
$this->_vars[] = $var->name;
}
}
return $this->_vars;
}
因此,有了它们,如果我想在编写/返回之前对它们进行操作,我可以自由地为属性创建额外的setter/getter。如果该属性不存在setter/getter,则返回到属性本身。使用方法getVars(),您可以从类中接收所有公共和受保护的属性。
我的类属性总是用undercorce定义的,所以你可能应该更改它。
您可以遵循此模式。
注意:在文章中的示例中,不会为$obj->data
、$obj->name
或$obj->age
调用magic方法,因为这些值已经可以作为公共属性访问。我把它们改成了受保护的,并把它们的名字改成了隐藏的。
<?php
class myMagic2{
protected $_data;
protected $_name;
protected $_age;
public function __set($item, $value){
switch($item){
case "data":
$this->_data = $value;
break;
case "name":
$this->_name = $value;
break;
case "age":
$this->_age = $value;
break;
default:
throw new Exception("Property $name does not exist.");
}
}
public function __get($item){
switch($item){
case "data":
return $this->_data;
break;
case "name":
return $this->_name;
break;
case "age":
return $this->_age;
break;
default:
throw new Exception("Property $name does not exist.");
break;
}
}
}
通常情况下,您会做更多的工作,然后使用magic方法作为代理来设置和获取类属性。您可以进行验证或筛选,或者以其他方式增强操作。如果你只是想获得或设置一个属性,那么你最好公开这些属性,放弃使用神奇的方法。