8

我正在重构一个广泛的代码库加班。从长远来看,我们将在类中开发整个系统,但与此同时,我正在利用这个机会来提高我的 PHP 技能并改进我们在数百个网站上使用的一些遗留代码。

随着时间的推移,我已经阅读了关于如何最好地从自定义函数返回数据的相互矛盾的文章,通常争论分为两类,一类关注最佳技术实践,另一类关注易于阅读和演示。

从自定义 PHP 函数返回时,我对您认为最佳实践的意见(详细说明)很感兴趣。

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

方法a。

填充返回变量并在函数末尾返回它:

<?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;
    }
}
?>

可能的重复可能是使用返回 true 或 false 的函数的 PHP 最佳实践是什么?然而,尽管我在上面的基本示例,这不仅限于简单的真或假。

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

扩展原始问题:

用于返回的方法是否因预期/期望的输出类型而异?

此方法是否会根据过程或面向对象的编程方法的使用而改变?正如这个问题所示,面向对象带来了它自己的怪癖,以进一步扩展可能的格式/表示选项PHP 中返回方法的最佳实践

请尽量在您的解释中清楚,我对您为什么选择您喜欢的方法以及是什么(如果有的话)让您选择它而不是另一种方法感兴趣。

4

6 回答 6

5

我倾向于提前返回——一旦你知道发生了什么就离开这个功能。这种用法的一种类型,如果称为“保护条款

我经常会做的其他事情包括放弃 finalelse作为默认值:

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

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

于 2015-05-15T09:58:29.947 回答
3

有人主张函数中的单一出口点(最后只有一个return),而其他人主张早早失败/返回。这只是根据具体情况的意见和可读性/可理解性问题。几乎没有任何客观的技术答案。

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

在您的具体情况下,两者都不是“最好的”;你的代码应该写成:

return $something > $somethingelse;

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

于 2015-05-15T09:56:09.070 回答
2

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

在返回值的情况下,我猜重要的是 可读性。有时最好为更易读和可维护的代码降低一点性能。
我将尝试展示一些有利弊的例子。

方法 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只是函数的最后一条语句,代码会更容易阅读,在 any 之外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 建议您创建一个其他函数来处理所有嵌套块的逻辑。一个函数应该是原子的,它应该只做一件事。如果它做了太多的工作,有太多的逻辑,就很难维护和理解。创建其他功能可能是一个不错的选择。

方法 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;
}

优点:

  • 默认值。在这个结构中,我们可以看到从一开始就处理了默认值。我们的函数中有逻辑,但如果我们没有进入任何分支,我们仍然有一个值。
  • 易于添加逻辑。如果我们需要添加一个分支if,这很容易并且不会改变函数的结构。

常数:

  • 不是必需的变量。在这种情况下,$return变量不是必需的,我们将编写相同的函数而不使用它。解决方案是到 return -1最后,并strlen($var)在 if 中返回,并且它的可读性不会降低。

结论

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

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

于 2018-03-03T11:45:43.633 回答
0

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

于 2015-05-15T09:46:32.663 回答
0

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

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

于 2015-05-15T09:56:00.643 回答
0
<?php
function theoreticalFunction( $var )
{
    if( $something > $somethingelse ){
       return true;
    }
    return false;
}
?>

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

于 2015-05-15T10:23:35.693 回答