多种返回类型php 7

myo*_*yol 39 php type-hinting php-7

我有一些方法可以返回两种返回类型之一 - (我正在使用一个利用MCV的框架,所以特别重构这几个函数并不吸引人)

是否可以声明返回类型返回一个或另一个并失败的其他任何东西?

function test(): ?
{
    if ($this->condition === false) {
        return FailObject;
    }

    return SucceedObject;
}
Run Code Online (Sandbox Code Playgroud)

bis*_*hop 75

截至目前,支持的方式是两个对象共享一个接口.例:

interface ReturnInterface {}
class FailObject implements ReturnInterface {}
class SuccessObject implements ReturnInterface {}
function test(): ReturnInterface {}
Run Code Online (Sandbox Code Playgroud)

在此示例中,ReturnInterface为空.它仅仅存在支持所需的返回类型声明.

警告:
以下讨论的RFC(联盟类型)已被拒绝
https://wiki.php.net/rfc/union_types

关于联合类型与几个竞争RFC有积极,热烈的讨论.如果其中任何一个通过,那么提议的签名将是:

function test(): FailObject|SuccessObject {}
Run Code Online (Sandbox Code Playgroud)

也就是说,无论联合类型如何,我都更喜欢接口方法.对我而言,它更清晰,更具可扩展性.如果我以后想要一个WarnObject我只需要将其定义为扩展ReturnInterface- 而不是通过所有签名并更新它们FailObject|SuccessObject|WarnObject.

  • 这实际上是有限的:想想entites(例如,使用Doctrine):不可能提示返回`null | Entity`.真的有限...... (11认同)
  • @Aerendir`null | Entity`在PHP 7.1中可用,具有可空类型:`?Entity`.请参阅https://secure.php.net/manual/en/migration71.new-features.php. (7认同)
  • @tangobango正如答案中所述:不,RFC被拒绝了. (4认同)
  • 你也可以在这里使用`abstract class`. (2认同)
  • @Aerendir解决方案/解决方法是让存储库方法返回一个包装null类型或实体的Option.以下是提供Option类型的包的示例:https://github.com/schmittjoh/php-option (2认同)

小智 46

正如bishop所指出的,有一个用于添加多种返回类型的RFC.但是,我想我会在PHP7.1中添加它,你现在可以指定一个可为空的返回类型,如下所示:

function exampleFunction(string $input) : ?int
{
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

所以这个函数会接受一个字符串,并在int之前添加问号,你允许它返回null或整数.

这是文档的链接:http: //php.net/manual/en/functions.returning-values.php

这里有一个引用该页面的引用解释用法:PHP 7.1允许在类型声明前加上void和null返回类型. - (例如函数canReturnNullorString():? string)

另外,这是另一个与此相关的线程: PHP7中的Nullable返回类型


vis*_*lex 19

PHP 7.2现在支持对象返回类型

http://php.net/manual/en/migration72.new-features.php

function test(object $obj) : object
// return any type of object ...
Run Code Online (Sandbox Code Playgroud)


yiv*_*ivi 11

从 PHP 8.0 开始,这是可能的

您现在可以使用联合类型来指定:

function test(): SucceedObject|FailObject
{
    if ($this->condition === false) {
        return FailObject;
    }

    return SucceedObject;
}
Run Code Online (Sandbox Code Playgroud)

事实上,这是可能的并不意味着它总是可取的。在很多(可能是大部分)的情况下,使用的接口(例如Result,这既FailSucceed将执行)作为建议在不同的答案,仍然是受欢迎得多。

但是在其他情况下,联合类型对于弱类型的替代可能有意义。例如,接受string和的方法int,或描述函数的返回类型,如stripos()返回int|false