在 PHP function/method 返回的最佳做法

Best practice for returning in PHP function/method

我正在加班重构大量代码库。在漫长的 运行 中,我们将在 类 中开发整个系统,但与此同时,我正在利用这个机会来完善我的 PHP 技能并改进我们使用的一些遗留代码跨越数百个网站。

随着时间的推移,我阅读了关于如何最好地从自定义函数中 return 数据的相互矛盾的文章,一般来说,争论分为两类,一类关注最佳技术实践,另一类关注阅读和演示的便利性.

我对 return 从自定义 PHP 函数调用时您认为最佳实践的意见(详细说明)很有趣。

我不确定以下哪一项是更好的标准,例如使用这个基本的理论函数;

方法a.

填充一个 return 变量并在函数末尾 return 对其进行处理:

<?php
function theoreticalFunction( $var )
{
    $return = '';
    if( $something > $somethingelse ){
       $return = true;
    }else{
       $return = false;
    }
    return $return;
}
?>

方法 b.

在每个端点返回:

<?php
function theoreticalFunction( $var )
{
    if( $something > $somethingelse ){
       return true;
    }else{
       return false;
    }
}
?>

一个可能的重复项可能是 What is the PHP best practice for using functions that return true or false? 但是尽管我上面的基本示例并不限于简单的真或假。

我查看了 PSR 指南,但没有看到任何内容(但我可能错过了它,所以请随时将我指向 PSR 并提供参考:))。

扩展原问题:

用于 return 的方法是否因 expected/desired 输出类型而异?

此方法是否会根据过程或面向对象编程方法的使用而改变?正如这个问题所示,面向对象带来了它自己的怪癖,以进一步扩展可能的 formatting/presentation 选项 Best practices for returns methods in PHP

请尽量在你的解释中说清楚,我很想知道你为什么选择你喜欢的方法,以及是什么让你选择它而不是另一种方法。

使用方法 b 对我来说更好,因为在方法 a 中你只写了很少的代码行,但是如果有很多代码行和很多 return 语句,那么我很可能会某处使用了错误的 return 类型,其中 $return 被分配到其他地方,我没有注意到。

我以前有变体 b。它不仅更具可读性(您确切地知道您不需要考虑 return 语句后的任何剩余代码),而且它也更安全。

如果您在剩余代码中存在错误,或者您遇到了一组您在设计系统时没有考虑到的条件,则您的结果可能会发生变化。使用 return [$someVariable] 退出函数时不会发生这种情况;

有人主张单退出点函数(最后只有一个return),也有人主张fail/return早。这只是一个意见问题,readability/comprehensibility 视具体情况而定。几乎没有任何 objective 技术答案。

现实情况是,它根本不是可以教条地规定的东西。有些算法用 A 表示更好,而另一些用 B 表示效果更好。

在您的特定情况下,"best" 也不是;你的代码应该写成:

return $something > $somethingelse;

这有望作为一个例子,表明根本没有普遍适用的规则。

我倾向于提早 returns - 一旦您知道发生了什么,就离开该功能。这种用法的一种类型称为 'Guard Clause'

我经常做的其他事情包括删除最终 else 作为默认值:

if ($something > $somethingelse) {
   return true;
}
return false;

事实上,if (boolean) return true; else return false 形式的条件可以进一步缩短(如果您更清楚)到 return ($something > $somethingelse);。从这样的代码中提取一个复杂的 if 子句到一个有用的命名函数可以帮助理清代码的含义。

<?php
function theoreticalFunction( $var )
{
    if( $something > $somethingelse ){
       return true;
    }
    return false;
}
?>

这种方式也可以用在on RETURN语句中,程序游标返回,不执行下一条语句。

我知道这个问题很老,但它很有趣,据我所知 有很多话要说。
首先要说的是,在函数或方法中 returning 并没有真正的标准。
它通常由您的团队决定遵循的规则决定,但如果您是唯一参与此重构的人,您可以做您认为更好的事情。

在 return 值的情况下,我想重要的是 可读性。有时候放松一点会更好 可读性和可维护性更高的代码的性能。
我将尝试展示一些有利有弊的例子。

方法 A

<?php
function getTariableType($var = null)
{
    if (null === $var) {
        return 0;
    } elseif (is_string($var)) {
        return 1;
    } else {
        return -1;
    }
}

优点:

  • 明确性。每个案例都有自己的解释,即使没有任何评论。
  • 结构。每个案子都有一个分支,每个案子都划清界限 并且很容易为新案例添加声明。

缺点:

  • 可读性。所有这些带括号的 if..else 使代码难以阅读和 我们真的必须注意每个部分才能理解。
  • 不需要代码。最后的 else 语句不是必需的,代码将是 如果 return -1 只是函数的最后一条语句,则更容易阅读, 在任何 else.
  • 之外

方法 B

<?php
function isTheVariableNull($var)
{
    return (null === $var);
}

优点:

  • 可读性。代码易于阅读和理解,乍一看我们 知道函数正在检查变量是否为空。
  • 简洁。只有一个声明,在这种情况下它很好很清楚。

缺点:

  • 限制。这种表示法仅限于非常小的功能。使用这个符号 甚至三元运算符在更复杂的情况下变得更难理解 函数。

方法 C.1

<?php
function doingSomethingIfNotNullAndPositive($var)
{
    if (null !== $var) {
        if (0 < $var) {
            //Doing something
        } else {
            return 0;
        }
    } else {
        return -1;
    }
}

优点:

  • 明确性。每个案例都是明确的,我们可以重构的逻辑 阅读时的功能。

缺点:

  • 可读性。当添加许多 if..else 语句时,代码确实更少 可读。然后代码缩进很多次看起来很脏。想象一下代码 有六个嵌套 if.
  • 难以添加代码。因为逻辑看起来很复杂(即使不是), 很难在函数中添加代码或逻辑。
  • 逻辑丰富。如果你有很多 if..else 嵌套,那可能是因为你 应该创建第二个功能。例如 NetBeans IDE 建议您创建 另一个处理所有嵌套块逻辑的函数。一个函数 应该是atomic,它应该只做一件事。如果它做了太多的工作,有 太多的逻辑,很难维护和理解。创建另一个函数 可能是个不错的选择。

方法 C.2

此方法旨在提供 C.1 表示法的替代方法。

<?php
function doingSomethingIfNotNullAndPositive($var)
{
    if (null === $var) {
        return -1;
    } elseif (0 >= $var) {
        return 0;
    }
    //Doing something
}

优点:

  • 可读性。这个符号非常可读。它是 很容易理解我们根据给定的值会得到什么结果。
  • 明确性。作为 C.1,这种方法在每个分支中都是明确的 条件。

缺点:

  • 难以添加逻辑。如果函数变得复杂一点, 添加逻辑会很困难,因为我们可能需要移动 条件。

方法 D

<?php
function kindOfStrlen($var)
{
    $return = -1;
    if (is_string($var)) {
        $return = strlen($var);
    }
    return $return;
}

优点:

  • 默认值。在这个结构中我们可以看到处理了默认值 从一开始就。我们的函数中有逻辑,但是如果我们输入 no 分支我们无论如何都有一个值。
  • 轻松添加逻辑。如果我们需要添加一个分支 if 很简单,但并不 更改函数的结构。

常量:

  • 不需要变量。在这种情况下,不需要 $return 变量,我们 会在不使用它的情况下编写相同的函数。解决方案是 return -1 在末尾,return strlen($var) 在 if 中,它不会 可读性较差。

结论

我没有在这里列出所有可能的符号,只列出了其中的一些。我们能做什么 想想他们是没有完美的,但在某些情况下,一种方法似乎 比另一个更好。例如,is_null 函数可以使用 方法 B.

使用一种方法还是另一种方法真的取决于你,重要的是 选择一个逻辑并在你的所有项目中保持它。