我没有找到我在这里发布的问题的完全重复,所以这里是:
class CBaseEntity
{
public function __construct()
{
}
public function __get($property)
{
$property = "m_".$property;
echo $property;
if(property_exists($this, $property))
{
$result = $this->$property;
return $result;
}
else
{
throw new Exception("Property not found $property");
}
}
}
class CCategoryEntity extends CBaseEntity
{
private $m_id;
private $m_name;
private $m_description;
public function __construct()
{
}
public static function CreateFromParams($id,$name, $description)
{
$instance = new CCategoryEntity();
$instance->m_id=$id;
$instance->m_name=$name;
$instance->m_description=$description;
return $instance;
}
public static function CreateFromArray(array $catData)
{
$instance = new CCategoryEntity();
$instance->m_id = $catData["id"];
$instance->m_name = $catData["name"];
$instance->m_description = $catData["description"];
return $instance;
}
}
$categoryEntity = CCategoryEntity::CreateFromParams(3, "EntityA", "Entity");
echo $categoryEntity->name;
Fatal error: Uncaught exception 'Exception' with message 'Property not found m_m_name'
Exception: Property not found m_m_name in ***\models\BaseModel.php on line 33
似乎name
属性是通过get
魔法解析的,但此getter正文中的返回将再次发出对自身的调用,而不是以某种方式智能地停止为$property
中的字符串与搜索属性的名称一致。我可以进行字符串比较,看看该属性是否以m_
开头,但我不想在这种情况下发出第二次调用。
还有其他涉及类似代码的SO问题,不会产生不必要的递归。在PHP中有什么变化或者这是默认行为吗?可以采取哪些措施以优雅的方式实现此设计的目标?
答案 0 :(得分:2)
我不知道你的意思,但没有第二次电话。当您在课堂外访问该媒体资源时,__get()
只会被调用一次。 <{1}}方法中的$this->$property
不会触发另一个电话。
从PHP文档:
在与属性交互时调用重载方法 或者尚未声明或在其中不可见的方法 目前的范围。
这意味着只有在没有可用于该调用的属性时才会调用__get()
方法。
答案 1 :(得分:2)
出现递归是因为您只检查属性是否存在,而不是从当前范围访问它。由于它被声明为私有,因此无法从父类或子类访问它,只能在声明它的类中访问,这就是为什么第二次调用__get
(首先是不存在的属性,现在是不可访问的属性) )。尝试get_object_vars以获取可访问的属性。
您可能希望对其进行保护,或者为私有属性定义公共getter方法。