【问题标题】:PHP method return without valuePHP方法返回无值
【发布时间】:2012-11-19 00:24:21
【问题描述】:

我正处于迁移到 100% OO php 的阶段,我最终遇到了很多这样的问题。所以,如果你觉得它很愚蠢,请原谅,我只是想在一开始就让我的 OO 编程实践很好,这样我以后就不必修复它们了。

这样做可以吗?

private function _some_funct($args) {
    // Some code here....
    if ($something) return;

    //Rest of code
}

基本上,这里有 2 个问题。

  1. return 后面没有值可以使用吗?我经常使用它并且没有遇到任何缺点,但从未在其他人的代码中看到它。我只看到return false

  2. 以这种方式停止函数通常可以吗,还是我应该重新考虑我的程序结构?

使用它的示例是我正在制作的 CMS。

public function _init_engines() {
    $this->_session_engine = $this->_dep['SessionEngine'];
    $this->_login_engine = $this->_dep['LoginEngine'];
    if ($this->_dep['User'] == false) return;   
    $this->_security_engine = $this->_dep['SecurityEngine'];
    //Other engines go here.......
}

所以我让系统启动会话并设置会话变量,然后检查用户是否已登录。如果用户未登录,LoginEngine 会处理并加载“登录”模块。加载登录模块后,我不希望实例化其他引擎,因为不需要它们。我本可以使用 dieexit 但这会阻止整个脚本执行。像这样,我的脚本完成执行,其他不是引擎的东西,比如基准测试和其他一些东西仍然被执行,这正是我想要的。再说一次,我应该在这里重新考虑我的逻辑还是您认为这样可以?

【问题讨论】:

  • 使用空返回来退出函数是完全可以的,但我通常只在所述函数是 void 函数时这样做(即:否则不会返回任何东西),并且可以不要像雷所说的那样进行重组。

标签: php oop return


【解决方案1】:

return 没有值是可以的,如果:

  1. 您的界面明确表示 - docblock 声明 @return void(如果函数中不需要结果值)或类似 @return sometype|null 的内容,其中 sometypestringint 等。
  2. 使用来自此类函数/方法的返回值的代码会在使用返回值之前检查 isset() - 如果使用您的代码的人(或您自己)忘记检查它,这可能会导致错误。

return 没有值是不行的,如果:

  1. 发生错误 - 请改用异常。异常更容易处理,因为您可以:
    1. 在外部范围内的任何地方捕获它们,甚至在全球范围内
    2. 传递漂亮的错误消息
    3. 扩展异常类以提供附加功能
    4. 准确检查引发的异常类型
  2. 预期某些特定的结果类型 - 在这种情况下,您可能会考虑一些默认的“空”结果,或者再次在出现问题时使用异常 - 它仍然比 isset 好得多,因为它更难忘记 - 异常是一种“大声”的方式来表示发生了错误。

请不要使用die()exit() 来“处理”错误 - 向用户显示错误的技术细节是一种非常糟糕的做法。

至于你的_init_engines() 方法——在不知道其余部分的情况下,真的很难说它是对还是错。

如果您对 PHP 中 OOP 的优秀示例感兴趣,我建议您查看 Symfony

【讨论】:

  • @return void 在 php read more here 或此 SO 答案中不被视为有效返回类型 here@987654324 @
  • 回复@Wilt 评论,第一个链接已损坏,第二个链接已更新显示现在有一个官方 RFC 用于 PHP wiki.php.net/rfc/void_return_type中的 void 类型
  • @James,感谢您的评论。我的评论已经 4 年了,所以我想事情已经改变了......我将不得不对今天被认为有效的内容进行一些新的阅读。
  • 对于阅读这些 cmets 的其他人,请检查 the docs on void return type shared by @James,显然在 PHP 7.1 中实现了返回 void 类型并被认为是有效的。
  • @James,没错!没有冒犯,只是为其他读者添加更正评论:D
【解决方案2】:

正如其他人所说,使用return; 没有缺点。您通常会看到return false;,因为通常最好在可能的情况下返回有意义的东西来确定函数做了什么。如果你的状态是“做什么都可以”,那么return;是完全可以接受的。

关于多次返回,我更喜欢在条件足以确定不应继续执行时使用多个退出点。例如,如果您需要User ID 而您没有收到,那么检查其余数据可能没有意义。在这种情况下,您可能会立即使用return RES_INVALID_USERID 之类的内容结束该函数。在这种情况下,我更喜欢多个return 而不是if..else 的链(嵌套时更糟)。

【讨论】:

    【解决方案3】:

    这深入研究了单返回点与多返回点的宗教战斗,但她我们去......

    使用许多没有任何价值或真正需要的返回作为执行流控制来避免继续执行功能是非常糟糕的形式。这有点像神奇的“goto”声明阵营。是的,你可以这样做,但我会投反对票,反对实际这样做,特别是如果在几个常见情况下,不只是早期的一些回报导致你的功能短路。

    为什么不重组你的函数,让它没有返回,但不执行它不需要的代码? 如果您发现您的函数/方法太大而易于重组,这可能是一个信号,这意味着您可能希望将它们分解为更小更简洁的方法/函数。

      public function _init_engines() {
        $this->_session_engine = $this->_dep['SessionEngine'];
        $this->_login_engine = $this->_dep['LoginEngine'];
        if ($this->_dep['User'] != false){ 
             $this->_security_engine = $this->_dep['SecurityEngine'];
        } else if (){
           //Other engines go here.......
        } 
        //no useless return needed
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-16
      • 2015-09-24
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 2023-03-09
      • 2020-01-10
      相关资源
      最近更新 更多