17

当我遇到问题时,我正在重构用于 PHP7 的代码库,特别是实现标量类型提示和返回类型提示。

我有一个具有一些属性的类,其中一个是 id。此 id 不是强制性的(您可以在不设置 id 的情况下构造对象)。在创建此类的新对象时,您不设置 id,并且一旦将其插入数据库(通过单独的映射器类),它就会获得一个 id。

这个映射器类需要检查对象是否已经存在于数据库中,它通过检查是否设置了 id 来做到这一点:

if(empty($exampleObject->getId())) {
    // Insert object
} else {
    // Update object
}

我正在对代码库中的每个函数应用返回类型提示,问题是如果我强制执行int返回类型,该函数getId()将无法返回NULL 。即使没有启用严格类型,它也会出现 TypeErrors:

致命错误:未捕获的 TypeError:ExampleClass::getId() 的返回值必须是整数类型,返回 null

我考虑过不为这个 getter 设置返回类型提示,但后来我意识到问题可能不是返回类型提示,而是我使用混合返回类型的事实。我记得在某处读到使用混合返回类型是一件坏事,但我不确定如何在不使用混合返回类型的情况下解决这个问题。我可以:

  • 在 getter 中抛出异常,并在映射器类中设计检查,以便捕获该异常。
  • 捕获 TypeError 异常,并使用它来指示 id 未设置。
  • 公开 id 属性,这样我就可以直接调用isset了。
  • 添加不同的方法hasId() return isset($this->id)

坦率地说,我不太喜欢这些解决方案,我想知道是否有更好的选择。这种情况的最佳做法是什么?

另外,如果我启用了严格输入,我不应该只得到一个 TypeError 吗?我认为 PHP7 默认为“弱类型提示”。

4

2 回答 2

27

PHP 7.1 添加了可空类型,在类型名称前放一个问号,将返回类型标记为同时接受该类型和 null:

public function getId(): ?int {
    /* … */
}

如果您仍在使用 PHP 7.0,我建议省略类型声明并使用 docblock。

于 2016-02-03T18:02:30.850 回答
0

使用null意味着使用面向对象的方法,因为值类型不能为空。因此,在整数类型周围使用类包装器可能很有用。例如,来自 SPL 类型的SplInt 。

于 2016-02-02T20:52:36.380 回答