【发布时间】:2018-11-25 09:29:13
【问题描述】:
应该如何使用 PHP 的魔法 __get() 和 __set() 方法并限制支持哪些属性?
我通常看到 PHP 的魔术方法用于重载以下两种方式,但都没有这样做。
我知道我可以硬编码一些逻辑,但这样做不会使类具有很强的可扩展性。
$obj1=new Entity1(new Foo, new Bar);
$obj1->propAccessible1='propAccessible1'; //Valid
var_dump($obj1->propAccessible1); //Valid
$obj1->privateObject1='privateObject1'; //Should not be allowed
var_dump($obj1->privateObject1); //Should not be allowed
$obj1->unsupportedProperty='unsupportedProperty'; //Correctly is not allowed
var_dump($obj1->unsupportedProperty); //Correctly is not allowed
$obj2=new Entity2(new Foo, new Bar);
$obj2->propAccessible1='propAccessible1'; //Valid
var_dump($obj2->propAccessible1); //Valid
$obj2->privateObject1='privateObject1'; //Should not be allowed
var_dump($obj2->privateObject1); //Should not be allowed (will be if first set using setter)
$obj2->unsupportedProperty='unsupportedProperty'; //Should not be allowed
var_dump($obj2->unsupportedProperty); //Should not be allowed
class Foo{}
class Bar{}
class Entity1
{
private $privateObject1, $privateObject2;
private $propAccessible1, $propAccessible2;
public function __construct($injectedObject1, $injectedObject2) {
$this->privateObject1=$injectedObject1;
$this->privateObject2=$injectedObject2;
}
public function __get($property) {
if (property_exists($this, $property)) return $this->$property;
else throw new \Exception("Property '$property' does not exist");
}
public function __set($property, $value) {
if (!property_exists($this, $property)) throw new \Exception("Property '$property' is not allowed");
$this->$property = $value;
return $this;
}
}
class Entity2
{
private $privateObject1, $privateObject2;
private $data=[];
public function __construct($injectedObject1, $injectedObject2) {
$this->privateObject1=$injectedObject1;
$this->privateObject2=$injectedObject2;
}
public function __set($property, $value) {
$this->data[$property] = $value;
}
public function __get($property) {
if (array_key_exists($property, $this->data)) {
return $this->data[$property];
}
else throw new \Exception("Property '$property' does not exist");
}
}
【问题讨论】:
-
什么是属性,请给我们一些属性的例子,如果你只想限制字符串或整数..等,我认为你可以使用类型声明,如果它是我认为的任何其他属性您需要在 setter 中对逻辑进行硬编码
-
@vSugumar 我主要关心的是不希望允许公开访问注入的对象。第二种方法实际上达到了这个目标,但是,它不限制支持的属性。以前,我使用过第一种方法,但是在完成这个练习之后,我认为第二种方法更好。是吗?
-
如果我正确理解您要执行的操作,您似乎可以将可访问的属性公开可见,而根本不使用魔术方法。我一定是错过了什么。
-
是的,在第二种方法中无法访问您注入的对象,但我仍然没有理解您的观点“它不限制支持的属性”请让我理解
-
@Don'tPanic 是的,我可以,但很多人会声称我不应该公开它们。
标签: php class overloading visibility getter-setter