Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以在PHP7上指定多个返回类型?_Php_Php 7_Type Hinting - Fatal编程技术网

是否可以在PHP7上指定多个返回类型?

是否可以在PHP7上指定多个返回类型?,php,php-7,type-hinting,Php,Php 7,Type Hinting,我有一些方法可以返回两种返回类型中的一种。我使用的是一个利用MCV的框架,所以重构这几个函数并不吸引人 是否可以声明返回一个或另一个的返回类型,并在其他任何方面失败 function test(): ? { if ($this->condition === false) { return FailObject; } return SucceedObject; } 从PHP 8+开始,您可以使用: 另一种方法是,两个对象共享一个接口,这种方法在PH

我有一些方法可以返回两种返回类型中的一种。我使用的是一个利用MCV的框架,所以重构这几个函数并不吸引人

是否可以声明返回一个或另一个的返回类型,并在其他任何方面失败

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

    return SucceedObject;
}
从PHP 8+开始,您可以使用:

另一种方法是,两个对象共享一个接口,这种方法在PHP4之后的所有版本中都可用。例如:

interface ReturnInterface {}
class FailObject implements ReturnInterface {}
class SuccessObject implements ReturnInterface {}
function test(): ReturnInterface {}
在本例中,
ReturnInterface
为空。它的存在支持所需的返回类型声明

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



对我来说,对于这个用例,接口比联合类型更清晰、更可扩展。例如,如果我以后想要一个
WarnObject
,我只需要将其定义为扩展
ReturnInterface
——而不是像bishop所指出的那样,遍历所有签名并将其更新为
FailObject | SuccessObject | WarnObject

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

function exampleFunction(string $input) : ?int
{
    // Do something
}
所以这个函数将接受一个字符串,通过在int之前添加问号,您允许它返回null或整数

以下是文档的链接:

下面是该页的一段引语,解释其用法:
PHP7.1通过在类型声明前面加上?-(例如函数canReturnNullorString():?字符串)


另外,这里还有一个与此相关的线程:

7.2以后的PHP支持对象返回类型


这不是正确的方式:

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
}
从PHP8.0开始

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

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

    return SucceedObject;
}
这是可能的,这并不意味着它总是可取的。在许多(可能是大多数)情况下,使用不同答案中建议的接口(例如,
结果
失败
成功
都将实现)仍然更可取


但在其他情况下,联合类型可以作为弱类型的替代品。例如,一种同时接受
string
int
的方法,或用于描述函数的返回类型,如,只有当
FailObject
SucceedObject
都共享一个接口或从一个公共父级扩展时,才会返回
int | false
这里还可以使用
抽象类:无法提示返回到
null |实体
。真正限制…@Aerendir的解决方案/解决方法是让repository方法返回一个包装null类型或实体的选项。下面是一个提供选项类型的包的示例:@tangobango,如回答中所述:否,RFC被拒绝。@Aerendir
null | Entity
在PHP7.1中提供了可空类型:
?Entity
。请参阅。不应使用异常来控制应用程序的流。实际上,您在这里将异常视为if语句,这不是异常的正确用法。您是说失败案例不是异常吗?嗯。。。最好返回一个“FailObject”并控制多个输出:if、elseif、elseif、else。(不)我建议代码结构正确,这样您就不需要依赖任何一种:)有必要设置stric类型来编写干净、可维护和健壮的代码。描述的案例(带有“FailObject”)是手动异常。控制流量也不例外。流程继续以成功案例为例。你不必在appcontroller之前控制异常。”通过“返回null对我有效,但void抛出异常”允许void和null返回类型。“…或null,无返回…”如果使用“return”,则错误变为:“具有返回类型的函数必须返回值”
try{
    $succeedObject = $any->test();
} catch (FailObjectException $exception){
    //do something
}
function test(): SucceedObject|FailObject
{
    if ($this->condition === false) {
        return FailObject;
    }

    return SucceedObject;
}