【发布时间】:2020-08-12 22:57:03
【问题描述】:
注入的对象是否有办法读取其父对象的属性?
这是一个例子:
这是一个field 对象,它包含字段的名称和值,并允许您注入验证规则:
class field
{
public string $name;
public $value;
public array $validators;
public function __construct($name, $value = null)
{
$this->name = $name;
$this->value = $value;
}
public function addValidator(validatorInterface $validator): field
{
$this->validators[] = $validator;
return $this;
}
public function validate()
{
foreach ($this->validators as $validator) {
if (! $validator->validate()) {
return false;
}
}
return true;
}
}
这里有几个验证器:
interface validatorInterface
{
public function validate(): bool;
}
class stringValidator implements validatorInterface
{
public function validate(): bool
{
return is_string($this->value);
}
}
class lengthValidator implements validatorInterface
{
public function validate(): bool
{
return strlen($this->value) > 3;
}
}
现在让我们来测试一下:
$name = new field('name', 'Robert');
$name->addValidator(new stringValidator);
$name->addValidator(new lengthValidator);
echo $name->validate() ? 'valid' : 'invalid';
显然它失败了,因为验证器不知道field 对象的$value 属性是什么。
首先想到的是在每个验证器中创建一个 setter,field 对象使用它来将值传递给每个验证器:
class field
{
[...]
public function addValidator(validatorInterface $validator): field
{
$this->validators[] = $validator;
$validator->setValue($this->value); // <--- new line
return $this;
}
[...]
}
class stringValidator implements validatorInterface
{
private $value;
public function setValue($value): validatorInterface // <--- new method
{
$this->value = $value;
return $this;
}
public function validate(): bool
{
return is_string($this->value);
}
}
但问题是,现在我需要遍历每个验证器,以便在新字段值发生更改时通知它们,这意味着 field 实例和 validatorInterface 实例都持有 @987654331 @ 那应该同步,但可能不是因为它们实际上不是同一个变量。
是否有任何直接的方法可以让注入的验证器“知道”field 实例的 value 属性是什么?
【问题讨论】:
-
不,无法自动执行此操作。对象引用只有一种方式。而且一个对象可以在多个地方注入,你会参考哪一个?
-
如果您需要这样做,您应该在包含该字段的验证器中添加一个属性,并将该字段传递给验证器构造函数。
-
那么将字段注入到被注入字段的验证器中?
-
是的,这样的交叉引用并不少见。
-
那是我缺少的非直观部分。你让我重新考虑了我的整个策略;谢谢。
标签: php oop dependency-injection