PHP 7.4+ class 属性 打字
PHP 7.4+ class property typing
我确定这个问题已经被问过很多次了,但我似乎找不到 good/satisfying 答案,所以请耐心等待。
使用 PHP 7.4+,我倾向于输入我能输入的所有内容。但是我对 Doctrine 实体属性有一些问题。
如果我输入的所有内容都正确,我通常会遇到很多这样的错误。
Typed property App\Entity\User::$createdAt must not be accessed before initialization
该类型错误的代码示例如下所示
/**
* @var DateTimeInterface
* @ORM\Column(type="datetime")
*/
protected DateTimeInterface $createdAt;
所以,我曾经使 属性 可以为 null,即使数据库字段不是。所以它看起来像这样。
/**
* @var DateTimeInterface|null
* @ORM\Column(type="datetime")
*/
protected ?DateTimeInterface $createdAt = null;
但是,现在我有另一个问题。我决定在我的项目中实现一个静态代码分析器,现在我正在使用 PHPStan。所以现在,当我扫描我的代码时,我会收到类似的错误。
Line src/Entity/Trait/TimestampableEntityPropertiesTrait.php (in context of class App\Entity\Article)
16 Property App\Entity\Article::$createdAt type mapping mismatch: property can contain DateTimeInterface|null but database expects DateTimeInterface.
那么,处理这种情况的正确方法是什么?
如有任何建议,我们将不胜感激。
编辑
我应该提到,有时我不想 to/can 不在构造函数中初始化 属性,因为我还没有正确的值。
我不确定这是否是一个坏习惯,但事实证明我只需要从 phpstan 配置中删除该检查。
# phpstan.neon
parameters:
doctrine:
allowNullablePropertyForRequiredField: true
编辑:
经过一些挖掘,我意识到我应该使用允许空值的 DTO,然后在准备好(且有效)后将其传输到我的实体。这样,我的实体总是有效的,我不会冒险刷新数据库中的一些无效数据。
phpstan
代码味道可能并没有那么错...
实际的 Doctrine 注释是 nullable=true
:
/**
* @ORM\Column(type="datetime", nullable=true)
*/
然后 ORM 将停止抱怨意外的 NULL
值。
没有它,created_at
将设置 NOT NULL
;因此它是“必需的”。
关键是,当它是 nullable=true
时,就不再需要它了。
而当它不再需要时,phpstan
也会停止抱怨
而另一方面,当让 phpstan
忽略与 allowNullablePropertyForRequiredField: true
在应用程序级别上的这些冲突时,这对基础数据库的影响为零,基础数据库将拒绝记录,基于用于生成数据库的注释 table.
我确定这个问题已经被问过很多次了,但我似乎找不到 good/satisfying 答案,所以请耐心等待。
使用 PHP 7.4+,我倾向于输入我能输入的所有内容。但是我对 Doctrine 实体属性有一些问题。
如果我输入的所有内容都正确,我通常会遇到很多这样的错误。
Typed property App\Entity\User::$createdAt must not be accessed before initialization
该类型错误的代码示例如下所示
/**
* @var DateTimeInterface
* @ORM\Column(type="datetime")
*/
protected DateTimeInterface $createdAt;
所以,我曾经使 属性 可以为 null,即使数据库字段不是。所以它看起来像这样。
/**
* @var DateTimeInterface|null
* @ORM\Column(type="datetime")
*/
protected ?DateTimeInterface $createdAt = null;
但是,现在我有另一个问题。我决定在我的项目中实现一个静态代码分析器,现在我正在使用 PHPStan。所以现在,当我扫描我的代码时,我会收到类似的错误。
Line src/Entity/Trait/TimestampableEntityPropertiesTrait.php (in context of class App\Entity\Article)
16 Property App\Entity\Article::$createdAt type mapping mismatch: property can contain DateTimeInterface|null but database expects DateTimeInterface.
那么,处理这种情况的正确方法是什么?
如有任何建议,我们将不胜感激。
编辑
我应该提到,有时我不想 to/can 不在构造函数中初始化 属性,因为我还没有正确的值。
我不确定这是否是一个坏习惯,但事实证明我只需要从 phpstan 配置中删除该检查。
# phpstan.neon
parameters:
doctrine:
allowNullablePropertyForRequiredField: true
编辑:
经过一些挖掘,我意识到我应该使用允许空值的 DTO,然后在准备好(且有效)后将其传输到我的实体。这样,我的实体总是有效的,我不会冒险刷新数据库中的一些无效数据。
phpstan
代码味道可能并没有那么错...
实际的 Doctrine 注释是 nullable=true
:
/**
* @ORM\Column(type="datetime", nullable=true)
*/
然后 ORM 将停止抱怨意外的 NULL
值。
没有它,created_at
将设置 NOT NULL
;因此它是“必需的”。
关键是,当它是 nullable=true
时,就不再需要它了。
而当它不再需要时,phpstan
也会停止抱怨
而另一方面,当让 phpstan
忽略与 allowNullablePropertyForRequiredField: true
在应用程序级别上的这些冲突时,这对基础数据库的影响为零,基础数据库将拒绝记录,基于用于生成数据库的注释 table.