PHP注入的对象可以访问注入对象的属性吗?

问题描述

注入的对象是否可以读取其父对象的属性?

这里是一个例子:

这是一个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属性是什么。

首先想到的是在每个field对象用来将值传递给每个验证器的验证器中创建一个setter:

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实例都是持有应该{em>应该同步的value,但这可能不是因为它们实际上不是同一变量。

是否有任何直接方法可以让注入的验证器“仅知道” field实例的value属性是什么?

解决方法

field对象传递给验证器而不是属性值,因为对象总是通过引用传递 课场 { [...]

    public function addValidator(validatorInterface $validator): field
    {
        $this->validators[] = $validator->setField($this);
        return $this;
    }

    [...]

}

class stringValidator implements validatorInterface
{
    private $field;
    
    public function setField($field): validatorInterface
    {
        $this->field = $field;
        return $this;
    }
    
    public function validate(): bool
    {
        return is_string($this->field->value);
    }
}

您可以像使用示例一样使用它:

$name = new field('name','Robert');
$name->addValidator(new stringValidator);
$name->addValidator(new lengthValidator);

echo $name->validate() ? 'valid' : 'invalid';

您可以在验证器的构造函数中传递field对象,但是每次添加验证器$name->addValidator(new stringValidator($name));时都需要传递该对象,因此上面的解决方案更好。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...