使用返回类型声明返回 NULL

Posted

技术标签:

【中文标题】使用返回类型声明返回 NULL【英文标题】:Returning NULL with return type declarations 【发布时间】:2016-05-11 20:15:02 【问题描述】:

当我遇到问题时,我正在重构用于 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 默认为“弱类型提示”。

【问题讨论】:

尝试int?作为返回类型 @tkausl 实现了吗?我不知道这个特性(它不在 PHP 文档中),但我发现了 this RFC(可空类型)。你指的是这个吗?如果是这样,这是针对 PHP 7.1 的草案。 哦.. 我确定我在某个地方看到过这个,但不确定在哪里,抱歉。 @tkausl,这是 C# 语法! re: 只在严格输入模式下获得TypeErrors,这不是它的工作原理。默认情况下,PHP 将尝试在类型之间进行强制转换,但在不可能的情况下,它会抛出 TypeError,至少对于用 PHP 编写的用户函数而言。但是,内置/扩展函数不会抛出 TypeError,除非在严格模式下。 【参考方案1】:

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

【讨论】:

【参考方案2】:

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

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

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

【讨论】:

谢谢。所以这意味着返回 NULL 本身没有任何问题? 是的,虽然有一些论点可以避免null,但它们并不普遍适用。 题外话,但我只是想指出 PSR2 为类和方法指定了开括号;) @wired00 我是个逆势者:p

以上是关于使用返回类型声明返回 NULL的主要内容,如果未能解决你的问题,请参考以下文章

CreateFile()函数的返回值,具体点的,有例子

使用所有类型的返回数据返回 null 值 Flutter

Access VBA - 为声明为 long 的函数返回某种空白/空值

sql语句返回null时报错的解决方案

类型错误:返回值必须是实例,返回null

条件参数和返回类型声明(又名类型提示)