PHP 7.1-为什么没有对void返回值的警告?

时间:2018-09-14 17:41:22

标签: php php-7.1

PHP manual notes在PHP 7.1中添加的新 void 返回类型概述中:this:

  

尝试使用void函数的返回值只会得出NULL,而不会发出警告。其原因是因为警告会暗示使用通用的高阶函数。

警告将暗示使用高阶函数”是什么意思?

3 个答案:

答案 0 :(得分:7)

  

高阶函数(HOF)是至少满足以下条件之一的函数-

     
      
  • 将一个或多个函数作为参数
  •   
  • 返回函数作为结果
  •   

source

然后从PHP Void RFC

  

return起;和return null;在技​​术上等同于PHP;如果未指定返回值,PHP将为您生成null。但是,选择一个建议则表示 intent 。如果指定一个值,则表明该值有意义。在void函数中,返回值无关紧要:它始终相同,没有实际用处。用return null显式指定它;毫无意义,因为因为函数返回的值并不重要。

(我的重点)

因此,根本不需要提供警告,它只需要使用另一个函数和额外的大量编译时开销,就可以故意通知一段代码中的返回错误,这些代码原意是不返回< / em>。

这样想:

  • 如果空牛奶纸箱被撞倒,我会准备很多海绵备用。

纸箱总是会被故意清空,因此无需在商店购买12块超强吸收性海绵!


要确切查看将调用哪些函数,请尝试探索PHP 7(开放源代码)的编译时错误处理逻辑;查看将调用哪些函数来处理导致类似错误的函数(例如返回无法识别或不正确的类型)。

这些函数将通过静默返回null而不是PHP 7.1预期的void返回类型错误而被不调用

答案 1 :(得分:5)

问题是这样的情况:

$users =User::where(id, $id)->WhereDoesntHave('followers')
                             ->ORwhereDoesntHave('following')
                             ->ORwhereDoesntHave('blocker')
                             ->ORwhereDoesntHave('blocking')
                              ->get();

此代码可以处理void和non-void函数。如果使用void函数的返回值会发出警告,那么我们将无法编写此代码,而必须执行以下操作:

class Forwarder {
    public $obj; // Some object
    public function __call($method, $args) {
        return $this->obj->$method(...$args);
    }
}

class Obj {
    public function returnsVal(): int { return 42; }
    public function returnsVoid(): void { return; }
}

$fwd = new Forwarder;
$fwd->obj = new Obj;

// We want both of these calls to work
$val = $fwd->returnsVal();
$fwd->returnsVoid();

这是很多不必要的样板,更不用说必须使用昂贵的反射调用来实现“ returns_void”。

答案 2 :(得分:4)

作为Martin回答的附录,我认为Void RFC的以下部分对澄清问题也很有帮助:

  

在表达式中使用void函数

     

在某些其他语言(例如C)中,void函数不能仅在语句中使用在表达式中。由于此RFC为PHP的语法添加了一种指定void函数的方法,因此可以预期,现在在PHP中将应用相同的限制。但是,这与先例不符。自从诞生以来,PHP就已经具有某种“空函数”,以内置函数的形式出现,在手册中记录为“空”。与C不同,此类函数可用于表达式中。

     

我们可以更改PHP在void函数上的规则,并禁止在表达式中使用它们,但这会产生向后兼容性的问题:现有的PHP代码依赖于能够在表达式中调用内置的void函数,这并非不可想象,并且大量代码假定您可以获取任意PHP函数(也许是回调)的返回值。

     

此外,当使用void函数的返回值时,IDE和其他工具可以警告用户。语言本身不一定必须涵盖这一点。

https://wiki.php.net/rfc/void_return_type#use_of_void_functions_in_expressions

TL; DR

PHP已经具有void内置函数,可在表达式中使用,而现在更改它将是一个很大的BC中断。