I am refactoring an extensive codebase overtime. In the long run we are going to develop the whole system in classes but in the mean time I am using the opportunity to refine my PHP skills and improve some of the legacy code we use across several hundred websites.
我一直在重构大量的代码基。从长远来看,我们将在类中开发整个系统,但同时,我正在利用这个机会改进我的PHP技能,改进我们在几百个网站上使用的一些遗留代码。
I have read conflicting articles over time about how best to return data from a custom function, generally the debate falls into two categories, those concerned about best technical practice and those concerned about ease of reading and presentation.
关于如何最好地从自定义函数返回数据,我已经阅读了一些相互矛盾的文章,一般来说,辩论分为两类,一类是关于最佳技术实践的,另一种是关于阅读和演示的易用性的。
I am interesting in opinions (with elaboration) on what you consider best practice when returning from a custom PHP function.
我对您在从自定义PHP函数返回时所考虑的最佳实践的看法很感兴趣。
I am undecided as to which of the following as a better standard to follow using this basic theoretical function for example;
我还没决定用这个基本的理论函数来遵循以下哪一个更好的标准;
Approach a.
方法一。
Populating a return variable and returning it at the end of the function:
填充返回变量并在函数末尾返回:
<?php
function theoreticalFunction( $var )
{
$return = '';
if( $something > $somethingelse ){
$return = true;
}else{
$return = false;
}
return $return;
}
?>
Approach b.
方法b。
Returning at each endpoint:
在每个端点返回:
<?php
function theoreticalFunction( $var )
{
if( $something > $somethingelse ){
return true;
}else{
return false;
}
}
?>
A possible duplicate could have been What is the PHP best practice for using functions that return true or false? however this is not limited to simply true or false despite my basic example above.
一个可能的副本是什么是PHP最佳实践使用返回真或假的函数?然而,这并不局限于简单的真或假,尽管我上面的基本例子是这样的。
I have looked through the PSR guidelines but didn't see anything (but I may have missed it so please feel free to point me to PSR with reference :) ).
我已经看了PSR的指导方针,但是没有看到任何东西(但是我可能错过了它,所以请随意给我指出PSR的参考:)。
Extending the original question:
扩展原始问题:
Is the method used to return different depending on the expected/desired output type?
返回的方法是否因预期/期望的输出类型而不同?
Does this method change depending on the use of procedural or object oriented programming methods? As this question shows, object orientation brings in its own eccentricities to further extend the possible formatting/presentation options Best practices for returns methods in PHP
这种方法是否会因使用面向过程或面向对象的编程方法而改变?正如这个问题所示,面向对象引入了它自己的怪癖来进一步扩展PHP中返回方法的格式/表示选项的最佳实践
Please try to be clear in your explanations, I am interested in WHY you choose your preferred method and what, if anything, made you choose it over another method.
请尽量解释清楚,我感兴趣的是你为什么选择你喜欢的方法,如果有的话,你会选择另一种方法。
6 个解决方案
#1
2
There are people arguing for single exit points in functions (only one return
at the end), and others that argue for fail/return early. It's simply a matter of opinion and readability/comprehensibility on a case-by-case basis. There is hardly any objective technical answer.
有些人主张函数中只有一个退出点(最后只有一个返回),而另一些人则主张尽早失败/返回。这只是一个观点和可读性/可理解性的问题。几乎没有任何客观的技术答案。
The reality is that it's simply not something that can be prescribed dogmatically. Some algorithms are better expressed as A and others work better as B.
事实上,它根本不是一种可以教条地规定的东西。有些算法更好地表示为A,有些算法更好地表示为B。
In your specific case neither is "best"; your code should be written as:
在你的具体情况下,两者都不是“最好的”;你的守则应写成:
return $something > $somethingelse;
That would hopefully serve as example that there's simply no such thing as a generally applicable rule.
希望这可以作为一个例子,说明根本没有一般适用的规则。
#2
5
I tend towards early returns - leave the function as soon as you know what is going on. One type of this use if called a 'Guard Clause'
我倾向于提前返回——只要你知道发生了什么,就离开这个函数。这种用法的一种,如果称为“Guard子句”
Other things I will often do include dropping final else
for a default:
我通常会做的其他事情包括放弃final else作为默认值:
if ($something > $somethingelse) {
return true;
}
return false;
and in fact, conditions of the form if (boolean) return true; else return false
, can be shortened even further (if it is clearer to you) to just return ($something > $somethingelse);
. Extracting a complex if clause from code like this to a usefully named function can help clear up the meaning of code a lot.
实际上,如果(布尔)返回真,则表单的条件;否则返回false,可以进一步缩短为(如果您更清楚的话)返回($ > $ else);从代码中提取一个复杂的if子句到一个有用的命名函数可以帮助清除代码的含义。
#3
0
Using the approach b is more fine with me because in approach a you have written very few lines of code, but if there are many lines of code and many return statements, then are chances that i will somewhere use the wrong return type, where $return was assigned a some other place and i did not notice that.
使用方法b更细跟我因为方法你写了几行代码,但如果有很多行代码和许多返回语句,然后某处的机会,我将用错误的返回类型,返回被分配一个美元的其他地方,我没有注意到。
#4
0
I prever variant b. Not only is it more readable ( you know exactly that you do not need to consider any of the remaining code after a return
statement), but it is also more failsafe.
我推荐变体b。它不仅可读性更好(您确切地知道,您不需要在返回语句之后考虑任何剩余的代码),而且它也更容易出错。
If you either have a bug in the remaining code, or you encounter a set of conditions you did not take into account when designing the system, it would be possible that your result is changed. This cannot happen when you exit the function with return [$someVariable]
;
如果您在余下的代码中有一个bug,或者您遇到了在设计系统时没有考虑到的一组条件,那么您的结果可能会发生变化。当您使用return [$someVariable]退出函数时,就不会发生这种情况;
#5
0
<?php
function theoreticalFunction( $var )
{
if( $something > $somethingelse ){
return true;
}
return false;
}
?>
This approach can also be used as on RETURN Statement, the program cursor is returned back and the next statement will not be executed.
这种方法也可以用于“返回”语句,返回程序游标,不执行下一个语句。
#6
0
I know this question is old but the it is interesting and according to me there are many things to say about it.
The first thing to say is that there is no real standard about returning in functions or methods.
It's usually ruled by the rules your team has decided to follow, but if you are the only one on this refactoring you can do what you think better.
我知道这个问题很老,但它很有趣,而且根据我的说法,有很多事情可以说明。首先要说的是,函数或方法的返回没有真正的标准。它通常是由您的团队决定遵循的规则所决定的,但是如果您是这个重构的唯一成员,您可以做您认为更好的事情。
In the case of returning a value the important thing I guess is readability. Sometimes it's better to loose a little bit of performance for a code that is more readable and maintainable.
I will try to show some examples with pros and cons.
在返回值的情况下,我认为重要的是可读性。有时,对于可读性和可维护性更强的代码来说,最好稍微降低一点性能。我将试着用正反两方面来展示一些例子。
Approach A
<?php
function getTariableType($var = null)
{
if (null === $var) {
return 0;
} elseif (is_string($var)) {
return 1;
} else {
return -1;
}
}
Pros:
优点:
- Explicitness. Each case explains itself, even without any comments.
- 直言不讳。即使没有任何评论,每个案例都能自我解释。
- Structure. There is a branch for each case, every case is delimited clearly and it's easy to add a statement for a new case.
- 结构。每个案例都有一个分支,每个案例都有清晰的分隔,并且很容易为新案例添加语句。
Cons:
缺点:
- Readability. All these
if..else
with brackets make the code hard to read and we really have to pay attention to every part to understand. - 可读性。所有这些如果. .否则,括号会使代码难于阅读,我们必须注意每个部分才能理解。
- Not required code. The last
else
statement is not required and the code would be easier to read if thereturn -1
was only the last statement of the function, outside of anyelse
. - 不需要代码。如果返回-1仅是函数的最后一个语句,而不是其他语句,则不需要最后一个else语句,那么代码就更容易读取。
Approach B
<?php
function isTheVariableNull($var)
{
return (null === $var);
}
Pros:
优点:
- Readability. The code is easy to read and understand, at the first look we know that the function is checking whether the variable is null.
- 可读性。代码易于阅读和理解,第一眼我们就知道函数正在检查变量是否为null。
- Conciseness. There is only one statement and in this case it's fine and clear.
- 简洁性。只有一种说法,在这种情况下很清楚。
Cons:
缺点:
- Limit. This notation is limited to really little funtions. Using this notation or even ternary operator becomes harder to understand in more complicated functions.
- 极限。这种表示法只适用于很少的函数。在更复杂的函数中,使用这种符号甚至三元运算符就更难理解了。
Approach C.1
<?php
function doingSomethingIfNotNullAndPositive($var)
{
if (null !== $var) {
if (0 < $var) {
//Doing something
} else {
return 0;
}
} else {
return -1;
}
}
Pros:
优点:
- Explicitness. Each case is explicit we can reconstruct the logic of the function when reading it.
- 直言不讳。每一种情况都是明确的,我们可以在阅读时重构函数的逻辑。
Cons:
缺点:
- Readability. When adding many
if..else
statements the code is really less readable. The code is then indented many times looks dirty. Imagine the code with six nestedif
. - 可读性。当添加许多如果. .else语句代码的可读性真的很差。然后代码多次缩进,看起来很脏。假设有六个嵌套的代码。
- Difficulty to add code. Because the logic seems complex (even if it is not), it's difficult to add code or logic into the function.
- 困难来添加代码。因为逻辑看起来很复杂(即使不是),所以很难在函数中添加代码或逻辑。
- Plenty of logic. If you have many
if..else
nested it is perhaps because you should create a second function. NetBeans IDE for example suggests you to create an other function that handles the logic of all your nested blocks. A function should be atomic, it should do only one thing. If it does too much work, has too much logic, it's hard to maintain and understand. Creating an other function may be a good option. - 大量的逻辑。如果你有很多如果。否则嵌套它可能是因为您应该创建第二个函数。例如,NetBeans IDE建议您创建一个处理所有嵌套块逻辑的其他函数。一个函数应该是原子的,它应该只做一件事。如果它做了太多的工作,有太多的逻辑,它很难维护和理解。创建另一个函数可能是一个不错的选择。
Approach C.2
This approch aims to present an alternative to the C.1 notation.
这种方法旨在提出c - 1表示法的一种替代方法。
<?php
function doingSomethingIfNotNullAndPositive($var)
{
if (null === $var) {
return -1;
} elseif (0 >= $var) {
return 0;
}
//Doing something
}
Pros:
优点:
- Readability. This notation is very readable. It's easy to understand what result we will get according to a given value.
- 可读性。这个符号很容易读。很容易理解根据给定的值我们会得到什么结果。
- Explicitness. As C.1, this approach is explicit in every branch of the condition.
- 直言不讳。作为C.1,这种方法在条件的每个分支中都是显式的。
Cons:
缺点:
- Difficulty to add logic. If the function becomes a bit more complicated, adding logic would be difficult because we may need to move all the branches of the condition.
- 添加逻辑困难。如果函数变得有点复杂,添加逻辑将会变得困难,因为我们可能需要移动条件的所有分支。
Approach D
<?php
function kindOfStrlen($var)
{
$return = -1;
if (is_string($var)) {
$return = strlen($var);
}
return $return;
}
Pros:
优点:
- Default value. In this structure we can see that the default value is handled from the beginning. We have logic in our function, but if we enter in no branch we have a value anyway.
- 默认值。在这个结构中,我们可以看到从一开始就处理了默认值。我们在函数中有逻辑,但是如果我们不输入分支,我们就有一个值。
- Ease to add logic. If we need to add a branch
if
it's easy and it does not change the structure of the function. - 轻松添加逻辑。如果我们需要添加一个分支如果它很简单并且不会改变函数的结构。
Const:
常量:
- Not required variable. In this case the
$return
variable is not required, we would write the same function without using it. The solution would be toreturn -1
at the end, and returnstrlen($var)
in the if, and it would not be less readable. - 不是必需的变量。在这种情况下,不需要$return变量,我们将不使用它而编写相同的函数。解决方案是在末尾返回-1,在if中返回strlen($var),这样就不会降低可读性。
Conclusion
I have not listed all the possible notation here, only some of them. What we can think about them is there is no perfect one, but in some cases an approach seems better that an other. For example an is_null function would be fine with the approach B.
我没有列出所有可能的符号,只有一些。我们能想到的是,没有完美的方法,但在某些情况下,一种方法似乎比另一种更好。例如,对于方法B, is_null函数是可以的。
Using an approach or an other is really up to you, the important thing is to choose a logic and to keep it during all your project.
使用一种方法或另一种方法完全取决于您,重要的是选择一个逻辑,并在整个项目期间保持它。
#1
2
There are people arguing for single exit points in functions (only one return
at the end), and others that argue for fail/return early. It's simply a matter of opinion and readability/comprehensibility on a case-by-case basis. There is hardly any objective technical answer.
有些人主张函数中只有一个退出点(最后只有一个返回),而另一些人则主张尽早失败/返回。这只是一个观点和可读性/可理解性的问题。几乎没有任何客观的技术答案。
The reality is that it's simply not something that can be prescribed dogmatically. Some algorithms are better expressed as A and others work better as B.
事实上,它根本不是一种可以教条地规定的东西。有些算法更好地表示为A,有些算法更好地表示为B。
In your specific case neither is "best"; your code should be written as:
在你的具体情况下,两者都不是“最好的”;你的守则应写成:
return $something > $somethingelse;
That would hopefully serve as example that there's simply no such thing as a generally applicable rule.
希望这可以作为一个例子,说明根本没有一般适用的规则。
#2
5
I tend towards early returns - leave the function as soon as you know what is going on. One type of this use if called a 'Guard Clause'
我倾向于提前返回——只要你知道发生了什么,就离开这个函数。这种用法的一种,如果称为“Guard子句”
Other things I will often do include dropping final else
for a default:
我通常会做的其他事情包括放弃final else作为默认值:
if ($something > $somethingelse) {
return true;
}
return false;
and in fact, conditions of the form if (boolean) return true; else return false
, can be shortened even further (if it is clearer to you) to just return ($something > $somethingelse);
. Extracting a complex if clause from code like this to a usefully named function can help clear up the meaning of code a lot.
实际上,如果(布尔)返回真,则表单的条件;否则返回false,可以进一步缩短为(如果您更清楚的话)返回($ > $ else);从代码中提取一个复杂的if子句到一个有用的命名函数可以帮助清除代码的含义。
#3
0
Using the approach b is more fine with me because in approach a you have written very few lines of code, but if there are many lines of code and many return statements, then are chances that i will somewhere use the wrong return type, where $return was assigned a some other place and i did not notice that.
使用方法b更细跟我因为方法你写了几行代码,但如果有很多行代码和许多返回语句,然后某处的机会,我将用错误的返回类型,返回被分配一个美元的其他地方,我没有注意到。
#4
0
I prever variant b. Not only is it more readable ( you know exactly that you do not need to consider any of the remaining code after a return
statement), but it is also more failsafe.
我推荐变体b。它不仅可读性更好(您确切地知道,您不需要在返回语句之后考虑任何剩余的代码),而且它也更容易出错。
If you either have a bug in the remaining code, or you encounter a set of conditions you did not take into account when designing the system, it would be possible that your result is changed. This cannot happen when you exit the function with return [$someVariable]
;
如果您在余下的代码中有一个bug,或者您遇到了在设计系统时没有考虑到的一组条件,那么您的结果可能会发生变化。当您使用return [$someVariable]退出函数时,就不会发生这种情况;
#5
0
<?php
function theoreticalFunction( $var )
{
if( $something > $somethingelse ){
return true;
}
return false;
}
?>
This approach can also be used as on RETURN Statement, the program cursor is returned back and the next statement will not be executed.
这种方法也可以用于“返回”语句,返回程序游标,不执行下一个语句。
#6
0
I know this question is old but the it is interesting and according to me there are many things to say about it.
The first thing to say is that there is no real standard about returning in functions or methods.
It's usually ruled by the rules your team has decided to follow, but if you are the only one on this refactoring you can do what you think better.
我知道这个问题很老,但它很有趣,而且根据我的说法,有很多事情可以说明。首先要说的是,函数或方法的返回没有真正的标准。它通常是由您的团队决定遵循的规则所决定的,但是如果您是这个重构的唯一成员,您可以做您认为更好的事情。
In the case of returning a value the important thing I guess is readability. Sometimes it's better to loose a little bit of performance for a code that is more readable and maintainable.
I will try to show some examples with pros and cons.
在返回值的情况下,我认为重要的是可读性。有时,对于可读性和可维护性更强的代码来说,最好稍微降低一点性能。我将试着用正反两方面来展示一些例子。
Approach A
<?php
function getTariableType($var = null)
{
if (null === $var) {
return 0;
} elseif (is_string($var)) {
return 1;
} else {
return -1;
}
}
Pros:
优点:
- Explicitness. Each case explains itself, even without any comments.
- 直言不讳。即使没有任何评论,每个案例都能自我解释。
- Structure. There is a branch for each case, every case is delimited clearly and it's easy to add a statement for a new case.
- 结构。每个案例都有一个分支,每个案例都有清晰的分隔,并且很容易为新案例添加语句。
Cons:
缺点:
- Readability. All these
if..else
with brackets make the code hard to read and we really have to pay attention to every part to understand. - 可读性。所有这些如果. .否则,括号会使代码难于阅读,我们必须注意每个部分才能理解。
- Not required code. The last
else
statement is not required and the code would be easier to read if thereturn -1
was only the last statement of the function, outside of anyelse
. - 不需要代码。如果返回-1仅是函数的最后一个语句,而不是其他语句,则不需要最后一个else语句,那么代码就更容易读取。
Approach B
<?php
function isTheVariableNull($var)
{
return (null === $var);
}
Pros:
优点:
- Readability. The code is easy to read and understand, at the first look we know that the function is checking whether the variable is null.
- 可读性。代码易于阅读和理解,第一眼我们就知道函数正在检查变量是否为null。
- Conciseness. There is only one statement and in this case it's fine and clear.
- 简洁性。只有一种说法,在这种情况下很清楚。
Cons:
缺点:
- Limit. This notation is limited to really little funtions. Using this notation or even ternary operator becomes harder to understand in more complicated functions.
- 极限。这种表示法只适用于很少的函数。在更复杂的函数中,使用这种符号甚至三元运算符就更难理解了。
Approach C.1
<?php
function doingSomethingIfNotNullAndPositive($var)
{
if (null !== $var) {
if (0 < $var) {
//Doing something
} else {
return 0;
}
} else {
return -1;
}
}
Pros:
优点:
- Explicitness. Each case is explicit we can reconstruct the logic of the function when reading it.
- 直言不讳。每一种情况都是明确的,我们可以在阅读时重构函数的逻辑。
Cons:
缺点:
- Readability. When adding many
if..else
statements the code is really less readable. The code is then indented many times looks dirty. Imagine the code with six nestedif
. - 可读性。当添加许多如果. .else语句代码的可读性真的很差。然后代码多次缩进,看起来很脏。假设有六个嵌套的代码。
- Difficulty to add code. Because the logic seems complex (even if it is not), it's difficult to add code or logic into the function.
- 困难来添加代码。因为逻辑看起来很复杂(即使不是),所以很难在函数中添加代码或逻辑。
- Plenty of logic. If you have many
if..else
nested it is perhaps because you should create a second function. NetBeans IDE for example suggests you to create an other function that handles the logic of all your nested blocks. A function should be atomic, it should do only one thing. If it does too much work, has too much logic, it's hard to maintain and understand. Creating an other function may be a good option. - 大量的逻辑。如果你有很多如果。否则嵌套它可能是因为您应该创建第二个函数。例如,NetBeans IDE建议您创建一个处理所有嵌套块逻辑的其他函数。一个函数应该是原子的,它应该只做一件事。如果它做了太多的工作,有太多的逻辑,它很难维护和理解。创建另一个函数可能是一个不错的选择。
Approach C.2
This approch aims to present an alternative to the C.1 notation.
这种方法旨在提出c - 1表示法的一种替代方法。
<?php
function doingSomethingIfNotNullAndPositive($var)
{
if (null === $var) {
return -1;
} elseif (0 >= $var) {
return 0;
}
//Doing something
}
Pros:
优点:
- Readability. This notation is very readable. It's easy to understand what result we will get according to a given value.
- 可读性。这个符号很容易读。很容易理解根据给定的值我们会得到什么结果。
- Explicitness. As C.1, this approach is explicit in every branch of the condition.
- 直言不讳。作为C.1,这种方法在条件的每个分支中都是显式的。
Cons:
缺点:
- Difficulty to add logic. If the function becomes a bit more complicated, adding logic would be difficult because we may need to move all the branches of the condition.
- 添加逻辑困难。如果函数变得有点复杂,添加逻辑将会变得困难,因为我们可能需要移动条件的所有分支。
Approach D
<?php
function kindOfStrlen($var)
{
$return = -1;
if (is_string($var)) {
$return = strlen($var);
}
return $return;
}
Pros:
优点:
- Default value. In this structure we can see that the default value is handled from the beginning. We have logic in our function, but if we enter in no branch we have a value anyway.
- 默认值。在这个结构中,我们可以看到从一开始就处理了默认值。我们在函数中有逻辑,但是如果我们不输入分支,我们就有一个值。
- Ease to add logic. If we need to add a branch
if
it's easy and it does not change the structure of the function. - 轻松添加逻辑。如果我们需要添加一个分支如果它很简单并且不会改变函数的结构。
Const:
常量:
- Not required variable. In this case the
$return
variable is not required, we would write the same function without using it. The solution would be toreturn -1
at the end, and returnstrlen($var)
in the if, and it would not be less readable. - 不是必需的变量。在这种情况下,不需要$return变量,我们将不使用它而编写相同的函数。解决方案是在末尾返回-1,在if中返回strlen($var),这样就不会降低可读性。
Conclusion
I have not listed all the possible notation here, only some of them. What we can think about them is there is no perfect one, but in some cases an approach seems better that an other. For example an is_null function would be fine with the approach B.
我没有列出所有可能的符号,只有一些。我们能想到的是,没有完美的方法,但在某些情况下,一种方法似乎比另一种更好。例如,对于方法B, is_null函数是可以的。
Using an approach or an other is really up to you, the important thing is to choose a logic and to keep it during all your project.
使用一种方法或另一种方法完全取决于您,重要的是选择一个逻辑,并在整个项目期间保持它。