多种返回类型php 7

时间:2016-05-04 16:21:21

标签: php php-7

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

是否可以声明返回类型返回一个或另一个而失败?

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

    return SucceedObject;
}

5 个答案:

答案 0 :(得分:63)

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

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

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

  

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

有关几种竞争RFC的联合类型的热烈讨论。如果其中任何一个通过,那么建议的签名将是:

function test(): FailObject|SuccessObject {}

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

答案 1 :(得分:30)

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

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

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

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

以下是该页面的引用解释用法: PHP 7.1允许使用类型声明前面的void和null返回类型。 - (例如,函数canReturnNullorString():? string)

此外,这是与此相关的另一个主题:Nullable return types in PHP7

答案 2 :(得分:16)

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

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

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

答案 3 :(得分:2)

PHP 8.0于2020年发布时,this will be possible

您将能够使用联合类型来指定以下内容:

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

    return SucceedObject;
}

这是可能的事实并不意味着它总是可取的。在很多(可能是大多数)情况下,使用接口(例如ResultFail都将实现的接口(例如Succeed)仍然是可取的。

但是在其他情况下,联合类型也可以替代弱类型。例如。既接受string也接受int的方法,或者描述返回stropos()的函数int|false的返回类型。

答案 4 :(得分:-1)

这不是正确的方法:

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

    return SucceedObject;
}

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

您应该定义一个例外:

class FailObjectException extends \Exception
{
    private $exampleExtraInfo;

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

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

现在,您可以定义如下功能:

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

    return SucceedObject;
}

并在try / catch中使用此功能:

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