PHP-从另一个对象检测对象上的更改

PHP-从另一个对象检测对象上的更改,php,oop,error-handling,Php,Oop,Error Handling,我正在尝试处理用户从实体对象生成的错误。 为此,我在实体对象中有一个errors属性 我当前的问题是,一些实体具有实体作为属性,因此这些子实体也具有错误属性 类实体 { 受保护的$errors=[]; //方法。。。 } 类用户扩展实体 { 保护$nick $something; 公共函数集昵称($val) { 如果(空($val)) { $this->errors[]=“不正确的刻痕”; } $this->nick=$val; } 公共函数get昵称() { 返回$this->nick; }

我正在尝试处理用户从实体对象生成的错误。 为此,我在实体对象中有一个
errors
属性

我当前的问题是,一些实体具有实体作为属性,因此这些子实体也具有
错误
属性

类实体
{
受保护的$errors=[];
//方法。。。
}
类用户扩展实体
{
保护$nick
$something;
公共函数集昵称($val)
{
如果(空($val))
{
$this->errors[]=“不正确的刻痕”;
}
$this->nick=$val;
}
公共函数get昵称()
{
返回$this->nick;
}
公共函数setSomeStuff(EntityObj$val)
{
$this->something=$val;
}
公共函数getSomeStuff()
{
返回$this->something;
}
}
类EntityObj扩展实体
{
保护$某物;
公共函数设置值($val)
{
如果//进行一些验证
{
$this->errors[]=“问题”;
}
$this->something=$val;
}

}
我认为您不必将错误存储在实体本身中。 我不知道你在这里使用什么版本的PHP,所以我想给你一些方法。 如果您在>PHP7中编写代码,那么您应该使用类型提示。这至少会阻止此实体使用空值

您可以将代码从

public function setNickName($val)
  {
    if (empty($val))
    {
      $this->errors[] = 'Incorrect nick';
    }

    $this->nick = $val;
  }

但我想你不想把空字符串作为昵称,也不想进行更多的验证。在这种情况下,您对该类的使用预期没有实现,因此它可能会引发异常?每当您的应用程序未达到预期,并且出现不正确的情况时,都会引发异常

public function setNickName(string $val)
{
    if($this->nick === ''){
        throw new \UserException('Empty Nickname is not allowed.')
    }
    // more verification, more exceptions ...

    $this->nick = $val
}
但正如您所猜测的,这是许多开发人员遇到的问题。看看这个常用框架的验证器组件

tl;博士: 如果删除errors属性,则不必在实体本身中存储错误。 开始使用类型提示如果您使用PHP7或更高版本来阻止代码进行验证,PHP可以自己处理部分代码。
也许可以使用现有的库来解决您的问题。

谢谢您的回答。创建错误属性的目的是能够通知用户他做错了什么。因此,对于多字段表单,每个他没有正确填写的字段都必须显示一个错误列表。如果我使用异常,代码将在第一次抛出异常后停止(对吗?),这不是我想要的。类型提示也是如此。。。我想让我的代码分析所有$\u POST变量,然后告知用户他做错了什么在我看来,您编写的用户类应该为用户存储数据,并且它可能每次都实例化用户的有效状态。使用这种方法,您的用户类只有一个目的——存储有效的用户数据。如果它存储错误并处理其验证,那么它将有多个用途。因此,最好将这些操作分开。最好将传入的数据存储在不同的对象中,并使用某种验证器对其进行验证,验证器接收数据并尝试将其逐个属性应用到用户类中。它收到的错误可以作为列表返回。也许可以考虑一下这种方法。
public function setNickName(string $val)
{
    if($this->nick === ''){
        throw new \UserException('Empty Nickname is not allowed.')
    }
    // more verification, more exceptions ...

    $this->nick = $val
}