是否可以在 PHP 7 上指定多种返回类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37033142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 01:02:20  来源:igfitidea点击:

Is it possible to specify multiple return types on PHP 7?

phpphp-7type-hinting

提问by myol

I have some methods that can return one of two return types. I'm using a framework utilizing MCV so refactoring these few functions in particular is not appealing.

我有一些方法可以返回两种返回类型之一。我正在使用一个利用 MCV 的框架,因此重构这几个功能特别不吸引人。

Is it possible to declare the return type returning one or the other and failing on anything else?

是否可以声明返回类型返回一个或另一个并在其他任何事情上失败?

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

    return SucceedObject;
}

回答by bishop

Before PHP 8, the standard way is for the two objects to share an interface. Example:

在 PHP 8 之前,标准的方式是两个对象共享一个接口。例子:

interface ReturnInterface {}
class FailObject implements ReturnInterface {}
class SuccessObject implements ReturnInterface {}
function test(): ReturnInterface {}

In this example, ReturnInterfaceis empty. Its mere presence supports the needed return type declaration.

在这个例子中,ReturnInterface是空的。它的存在支持所需的返回类型声明。

You could also use a base, possibly abstract, class.

您还可以使用基础类,可能是抽象类。



As of PHP 8+, you may alsouse union types:

从 PHP 8+ 开始,您还可以使用联合类型

function test(): FailObject|SuccessObject {}

To me, for this use case, interfaces are more clear and more extensible. For example, if I later want a WarnObjectI need only to define it as extending ReturnInterface-- rather than going through all signatures and updating them to FailObject|SuccessObject|WarnObject.

对我来说,对于这个用例,接口更清晰,更可扩展。例如,如果我以后想要一个,WarnObject我只需要将它定义为扩展ReturnInterface——而不是遍历所有签名并将它们更新为FailObject|SuccessObject|WarnObject.

回答by david.lee

As noted by bishop, there is an RFC for adding multiple return types. However, I thought I'd add that as of PHP7.1 you can now specify a nullable return type like this:

正如 bishop 所指出的,有一个用于添加多个返回类型的 RFC。但是,我想我会补充说,从 PHP7.1 开始,您现在可以指定一个可为空的返回类型,如下所示:

function exampleFunction(string $input) : ?int
{
    // Do something
}

So this function would take in a string and by adding the question mark before int you are allowing it to return either null or an integer.

因此,此函数将接收一个字符串,并通过在 int 之前添加问号来允许它返回 null 或整数。

Here's a link to the documentation: http://php.net/manual/en/functions.returning-values.php

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

And here's a quote from that page explaining the usage: PHP 7.1 allows for void and null return types by preceding the type declaration with a ? — (e.g. function canReturnNullorString(): ?string)

这是该页面中解释用法的引用:PHP 7.1 通过在类型声明之前使用 ? —(例如函数 canReturnNullorString(): ?string)

Also, here's another thread that relates to this: Nullable return types in PHP7

此外,这是与此相关的另一个线程: PHP7 中的 Nullable return types

回答by visualex

PHP from 7.2 onward supports the object return type

PHP 从 7.2 开始支持对象返回类型

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

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

function test(object $obj) : object
// return any type of object ...

回答by yivi

When PHP 8.0 is released in 2020, this will be possible.

当 PHP 8.0 于 2020 年发布时,这将成为可能

You will be able to use union types to specify this:

您将能够使用联合类型来指定这一点:

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

    return SucceedObject;
}

The fact that this is possible does not mean that it is always advisable. In many (probably most) situations, using an interface (e.g. Result, which both Failand Succeedwould implement) as advised in a different answer, is still much preferable.

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

But there are other instances where union types could make sense to an alternative to weak typing. E.g. a method that accepts both stringand int, or to describe the return type of a function like stripos(), which returns int|false.

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

回答by calmohallag

This ins't correct way:

这不是正确的方法:

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

    return SucceedObject;
}

Multiple return type is a bad practice.Good practices:

多重返回类型是一种不好的做法。良好做法:

You should define a exception:

您应该定义一个异常:

class FailObjectException extends \Exception
{
    private $exampleExtraInfo;

    public function __construct($exampleExtraInfo, $message)
    {
        parent::__construct($message);
        $this->exampleExtraInfo = $exampleExtraInfo;
    }

    public function exampleExtraInfo(): int
    {
        return $this->exampleExtraInfo;
    }
}

Now, you can define function like:

现在,您可以定义如下函数:

function test(): SucceedObject
{
    if ($this->condition === false) {
        throw new FailObjectException(...,...);
    }

    return SucceedObject;
}

And use this function with try/catch:

并在 try/catch 中使用此函数:

try{
    $succeedObject = $any->test();
} catch (FailObjectException $exception){
    //do something
}