Standards for exiting a function [duplicate] - php

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why should a function have only one exit-point?
As a CS student I have had it beaten into my head that there should only be one exit point in a function, at the end.
eg. This:
function foo()
{
//do stuff here
if($bar)
{
$out = FALSE;
}
else
{
$out = TRUE;
}
return $out;
}
Not:
function foo()
{
//do stuff here
if($bar)
{
return FALSE;
}
return TRUE;
}
However I have seen this second type of exiting used quite often in other peoples code in php, and even in core code for some frameworks (like Kohana which I have been using lately).
Is this method of exiting a function considered okay in php standards?
Edit: I can see why I have been told not to do it as it can be easier to track some problems in a function with one exit point, other times I can see why it should be allowed as other problems are better solved or tracked in functions with multiple exit points.
Edit 2: Added "do stuff here" comments to the code example to make people happy

I've always used the latter route, since you would have to declare $out and have one more variable in existence. But in retrospect, it's just a boolean -- it's not doing any harm. The first route could look cleaner, depending on the context of your code.
It all comes down to consistency. As long as you have a system, determining when it is time to use route 1 or route 2, you're doing great.

It's six of one, or half a dozen of another - happiness lies in consistency.

I've seen (good) code return values both ways. If you're using a framework/codebase that consistently uses one way, I would follow that. Otherwise, use what you're comfortable using. :D

Related

Is it a good alternative of nested if-statement in PHP? [duplicate]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
It occurs to me that there are number of different ways to structure conditional logic. As far as I can see, as long as we set errors to end the script (or you can imagine the same examples but with a return in a function), then the following examples are equal:
Example 1
if($condition1) {
trigger_error("The script is now terminated");
}
if($condition2) {
trigger_error("The script is now terminated");
}
echo "If either condition was true, we won't see this printed";
Example 2
if(!$condition1) {
if(!$condition2) {
echo "If either condition was true, we won't see this printed";
}
else {
trigger_error("The script is now terminated");
}
}
else {
trigger_error("The script is now terminated");
}
Example 3
if($condition1) {
trigger_error("The script is now terminated");
}
else {
if($condition2) {
trigger_error("The script is now terminated");
}
else {
echo "If either condition was true, we won't see this printed";
}
}
Example 4 -- Adapted from Fraser's Answer
function test($condition) {
if($condition) {
trigger_error("The script is now terminated");
}
}
test($condition1);
test($condition2);
echo "If either condition was true, we won't see this printed";
Personally, I lean towards writing code as in Example 1. This is because I feel that by checking for conditions that end the script (or function) in this way, I can clearly define what the script executed and not executed i.e. everything before the condition has been executed and everything after the line has not. This means when I get an error on line 147, I know immediately what has happened helping me to find a bug faster. Furthermore, if I suddenly realise I need to test $condition2 before $condition1, I can make a change by a simple copy paste.
I see a lot of code written like in Example 2 but for me, this seems much more complex to debug. This is because, when the nesting gets too great, an error will get fired off at some distant line at the bottom and be separated from the condition that caused it by a huge chunk of nested code. Additionally, altering the conditional sequence can be a lot messier.
You could hybrid the two styles, such as in Example 3, but this then seems to overcomplicate matters because all of the 'else's are essentially redundant.
Am I missing something? What is the best way to structure my conditional code? Is there a better way than these examples? Are there specific situations under which one style may be superior to another?
Edit: Example 4 looks quite interesting and is not something I had considered. You could also pass in an error message as a second parameter.
Thanks!
P.S. Please keep in mind that I might need to do some arbitrary steps inbetween checking $condition1 and $condition2 so any alternatives must accommodate that. Otherwise, there are trivially better alternatives such as if($condition1 || $condition2).
I am in the Example 1 camp. As a rule of thumb, the less indentation needed, the better.
// Exit early if there are errors.
if ($n < 0) {
die "bad n: $n";
}
// Handle trivial cases without fuss.
if ($n == 0) {
return 0;
}
/* Now the meat of the function. */
$widget->frob($n);
foreach ($widget->blaxes as $blax) {
checkFrobbingStatus($blax);
}
// ...And another 20 lines of code.
When you use an if/else and put the success and error code in parallel sections you make it appear as if the two code blocks are equal. In reality, the edge cases and error conditions should be de-emphasized. By intentionally handling errors early and then not putting the "important" code in an else clause I feel like that makes it visually clearer where the important code is.
"Here are all the preconditions. And now here's the good stuff."
Personally I hate nested if-else statements so #1 for me from your examples. The other option I would look at is something like the following.
function test($condition) {
if($condition) {
trigger_error("The script is now terminated");
}
}
test($condition1);
//do stuff...
test($condition2);
//passed the tests
EDIT: The more I think about it a functional approach is by far the best way in that it negates having to write the logic that tests the conditions more than once. It also allows greater readability because it is obvious you are 'testing' the condition (as long as you give the function a meaningful name). Also, as pointed out in the question edit it would be trivial to pass other parameters to the function. i.e.
function test($c, $msg) {
if($c) {
trigger_error($msg);
}
}
test($condition1, "condition1 error");
test($condition2, "condition2 error");
#1 is by far the clearest. However, if somehow the thing that previously ended the execution were changed to do something else, then it would break.
It's still probably best to go with #1, but make sure the thing being used to "stop" is clearly named to indicate that it does stop things, so that someone in 10 years maintaining your code doesn't accidentally break things by changing it.
I think your method (example 1) is the most efficient and effective in this type of situation. However, there are times when you do not want any conditions to halt execution and you only want to execute condition2 if condition1 is false. In these situations, an else or elseif works well.
I suggest using ‘try‘ clause over any part that can have errors and use ‘throw "error description"‘ each time an error occures(like example #1).
That way you can have error reporting code once in your program (in the ‘catch‘ clause) and splitting code into functions won't be a hussle rewriting error handlig.
I prefer this style, which doesn't break if either of the conditional blocks are changed so they do not exit execution.
if($condition1) {
trigger_error("The script is now terminated");
}
if($condition2) {
trigger_error("The script is now terminated");
}
if (!$condition1 && !$condition2) {
echo "If either condition was true, we won't see this printed";
}
Edit: Missed the PS, so updated code to match the full question details.
I generally agree with Amber insofar as your first option seems the most legible. This is something I have fought with myself - thus far the only reasoning I have stumbled across is as follows:
The first form is clearest when reading through a linear script, so ideal for simple scripts
The second form is cleanest when you need to ensure tidy / clean-up operations
I mention the second because this is a sticky point. Each script may be part of a larger system, and in fact the script elements you are injecting the "bail out" code into may be called by multiple places. Throw in some OO and you've got a real potential pickle.
The best rule of thumb I can recommend is that if your scripts are simple and linear, or your are doing rapid prototyping, then you want to use the first form and just kill the execution at that point. Anything more complicated or "enterprise-esque" will benefit from (at least) a modular redesign so you can isolate the method and the call stack - and possibly encapsulation of an OO build.
With some of the more powerful debugging and tracing tools which are available these days, it is becoming more a matter of personal style than necessity. One other option you might consider is to put information in comments before (and possibly after) each bail-out zone which make it clear what the alternative is should the criteria be met (or failed).
Edit:
I'd say Fraser's answer is the cleanest for encapsulation. The only thing I would add it that you might benefit from passing an object or hash array into the standard "bail out, I'm dead" method so you can modify the information made available to the function without changing parameter lists all the time (very annoying...).
That said - be careful in production systems where you may need to clean up resources in an intermediate state.
I much prefer #1 as well.
In addition, I really like to assign variables during the conditionals
e.g.
if ( !$userName = $user->login() ) {
die('could not log in');
}
echo "Welcome, $username";
I usually find that in the first write of code, I end up with a fair few messy nested conditional statements, so it's usually during a second pass that I go back and clean things up, un-nest as many of the conditionals that I can.
In addition to looking much neater, I find it conceptually much easier to understand code where you don't have to mentally keep track of branching logic.
For branching logic that can't be removed that contains lots of procedural code, I usually end up putting it in a function / class method -- ideally so I can see on one screen all the branching logic that is taking place, but modifying either the actions or the logic won't break the other one.
Example 5
if($condition1 || $condition2)
{
echo "If either condition was true, we won't see this printed";
}else
{
trigger_error("The script is now terminated");
}
Example 6
function allAreTrue()
{
foreach(func_get_args() as $check)
{
if(!$check)
{
return false;
}
}
return true;
}
if(allAreTrue(true,true,$condition1,$condition2,false))
{
exit("Invalid Arguments");
}
//Continue
The best way to structure conditional logic is to follow the logic itself.
If you have dependencies, say, failing of first condition will make others unnecessary is one thing. Then return, goto, nested conditions and exceptions at your choice.
If you are about to make decision upon a test, say
if (!isset($_GET['id'])) {
//listing part:
} else {
// form displaying part:
}
it's else, elseif and case realm.
etc.
Determine your program logic first and write it's logic then.
and trigger_error() has nothing to do with conditions. It is debugging feature, not program logic related one.

Is there a better way to write the following?

I got confronted with this "problem" several times already, I fix it the same way but I feel dirty just by thinking how I solved it.
Let's say I work with Drupal 8 and that I need to modify several select form's default value, "-Any-" by "Select...".
This is how I proceed each time :
if(isset($form['field_children_charge_value'])) {
$form['field_children_charge_value']['#options']['All'] = t('Select...');
}
if(isset($form['field_evolution_target_id'])) {
$form['field_evolution_target_id']['#options']['All'] = t('Select...');
}
// And so on
I feel bad writing like this, but, for my defense, I didn't have a lot of of PHP theory while learning, I directly got the practical courses.
an elseif expression would only work once since the first condition will match the pre requisite, and it won't bother checking if some other condition would work too.
I also got the problem once with javascript, and I did the same thing.
So, is there a better syntax, and if yes, what is it?
Been years since I coded in php, but this seems like a general "issue".
You can save all the fields in an array, and then use a for-each loop to execute the operation on each of them:
$fields = ["field1", "field2", "..."];
foreach($fields as $field) {
if(isset($form[$field])) {
$form[$field]['#options']['All'] = t('Select...');
}
}

Best practice for returning in PHP function/method

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.
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.
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.
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.
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 :) ).
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
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.
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'
Other things I will often do include dropping final else for a default:
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.
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.
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.
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 the return -1 was only the last statement of the function,
outside of any 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.
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 nested if.
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.
Approach C.2
This approch aims to present an alternative to the C.1 notation.
<?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.
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 to
return -1 at the end, and return strlen($var) in the if, and it would not
be less readable.
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.
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.
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.
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.
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];
<?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.

What is the best way to structure conditional logic? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 12 years ago.
It occurs to me that there are number of different ways to structure conditional logic. As far as I can see, as long as we set errors to end the script (or you can imagine the same examples but with a return in a function), then the following examples are equal:
Example 1
if($condition1) {
trigger_error("The script is now terminated");
}
if($condition2) {
trigger_error("The script is now terminated");
}
echo "If either condition was true, we won't see this printed";
Example 2
if(!$condition1) {
if(!$condition2) {
echo "If either condition was true, we won't see this printed";
}
else {
trigger_error("The script is now terminated");
}
}
else {
trigger_error("The script is now terminated");
}
Example 3
if($condition1) {
trigger_error("The script is now terminated");
}
else {
if($condition2) {
trigger_error("The script is now terminated");
}
else {
echo "If either condition was true, we won't see this printed";
}
}
Example 4 -- Adapted from Fraser's Answer
function test($condition) {
if($condition) {
trigger_error("The script is now terminated");
}
}
test($condition1);
test($condition2);
echo "If either condition was true, we won't see this printed";
Personally, I lean towards writing code as in Example 1. This is because I feel that by checking for conditions that end the script (or function) in this way, I can clearly define what the script executed and not executed i.e. everything before the condition has been executed and everything after the line has not. This means when I get an error on line 147, I know immediately what has happened helping me to find a bug faster. Furthermore, if I suddenly realise I need to test $condition2 before $condition1, I can make a change by a simple copy paste.
I see a lot of code written like in Example 2 but for me, this seems much more complex to debug. This is because, when the nesting gets too great, an error will get fired off at some distant line at the bottom and be separated from the condition that caused it by a huge chunk of nested code. Additionally, altering the conditional sequence can be a lot messier.
You could hybrid the two styles, such as in Example 3, but this then seems to overcomplicate matters because all of the 'else's are essentially redundant.
Am I missing something? What is the best way to structure my conditional code? Is there a better way than these examples? Are there specific situations under which one style may be superior to another?
Edit: Example 4 looks quite interesting and is not something I had considered. You could also pass in an error message as a second parameter.
Thanks!
P.S. Please keep in mind that I might need to do some arbitrary steps inbetween checking $condition1 and $condition2 so any alternatives must accommodate that. Otherwise, there are trivially better alternatives such as if($condition1 || $condition2).
I am in the Example 1 camp. As a rule of thumb, the less indentation needed, the better.
// Exit early if there are errors.
if ($n < 0) {
die "bad n: $n";
}
// Handle trivial cases without fuss.
if ($n == 0) {
return 0;
}
/* Now the meat of the function. */
$widget->frob($n);
foreach ($widget->blaxes as $blax) {
checkFrobbingStatus($blax);
}
// ...And another 20 lines of code.
When you use an if/else and put the success and error code in parallel sections you make it appear as if the two code blocks are equal. In reality, the edge cases and error conditions should be de-emphasized. By intentionally handling errors early and then not putting the "important" code in an else clause I feel like that makes it visually clearer where the important code is.
"Here are all the preconditions. And now here's the good stuff."
Personally I hate nested if-else statements so #1 for me from your examples. The other option I would look at is something like the following.
function test($condition) {
if($condition) {
trigger_error("The script is now terminated");
}
}
test($condition1);
//do stuff...
test($condition2);
//passed the tests
EDIT: The more I think about it a functional approach is by far the best way in that it negates having to write the logic that tests the conditions more than once. It also allows greater readability because it is obvious you are 'testing' the condition (as long as you give the function a meaningful name). Also, as pointed out in the question edit it would be trivial to pass other parameters to the function. i.e.
function test($c, $msg) {
if($c) {
trigger_error($msg);
}
}
test($condition1, "condition1 error");
test($condition2, "condition2 error");
#1 is by far the clearest. However, if somehow the thing that previously ended the execution were changed to do something else, then it would break.
It's still probably best to go with #1, but make sure the thing being used to "stop" is clearly named to indicate that it does stop things, so that someone in 10 years maintaining your code doesn't accidentally break things by changing it.
I think your method (example 1) is the most efficient and effective in this type of situation. However, there are times when you do not want any conditions to halt execution and you only want to execute condition2 if condition1 is false. In these situations, an else or elseif works well.
I suggest using ‘try‘ clause over any part that can have errors and use ‘throw "error description"‘ each time an error occures(like example #1).
That way you can have error reporting code once in your program (in the ‘catch‘ clause) and splitting code into functions won't be a hussle rewriting error handlig.
I prefer this style, which doesn't break if either of the conditional blocks are changed so they do not exit execution.
if($condition1) {
trigger_error("The script is now terminated");
}
if($condition2) {
trigger_error("The script is now terminated");
}
if (!$condition1 && !$condition2) {
echo "If either condition was true, we won't see this printed";
}
Edit: Missed the PS, so updated code to match the full question details.
I generally agree with Amber insofar as your first option seems the most legible. This is something I have fought with myself - thus far the only reasoning I have stumbled across is as follows:
The first form is clearest when reading through a linear script, so ideal for simple scripts
The second form is cleanest when you need to ensure tidy / clean-up operations
I mention the second because this is a sticky point. Each script may be part of a larger system, and in fact the script elements you are injecting the "bail out" code into may be called by multiple places. Throw in some OO and you've got a real potential pickle.
The best rule of thumb I can recommend is that if your scripts are simple and linear, or your are doing rapid prototyping, then you want to use the first form and just kill the execution at that point. Anything more complicated or "enterprise-esque" will benefit from (at least) a modular redesign so you can isolate the method and the call stack - and possibly encapsulation of an OO build.
With some of the more powerful debugging and tracing tools which are available these days, it is becoming more a matter of personal style than necessity. One other option you might consider is to put information in comments before (and possibly after) each bail-out zone which make it clear what the alternative is should the criteria be met (or failed).
Edit:
I'd say Fraser's answer is the cleanest for encapsulation. The only thing I would add it that you might benefit from passing an object or hash array into the standard "bail out, I'm dead" method so you can modify the information made available to the function without changing parameter lists all the time (very annoying...).
That said - be careful in production systems where you may need to clean up resources in an intermediate state.
I much prefer #1 as well.
In addition, I really like to assign variables during the conditionals
e.g.
if ( !$userName = $user->login() ) {
die('could not log in');
}
echo "Welcome, $username";
I usually find that in the first write of code, I end up with a fair few messy nested conditional statements, so it's usually during a second pass that I go back and clean things up, un-nest as many of the conditionals that I can.
In addition to looking much neater, I find it conceptually much easier to understand code where you don't have to mentally keep track of branching logic.
For branching logic that can't be removed that contains lots of procedural code, I usually end up putting it in a function / class method -- ideally so I can see on one screen all the branching logic that is taking place, but modifying either the actions or the logic won't break the other one.
Example 5
if($condition1 || $condition2)
{
echo "If either condition was true, we won't see this printed";
}else
{
trigger_error("The script is now terminated");
}
Example 6
function allAreTrue()
{
foreach(func_get_args() as $check)
{
if(!$check)
{
return false;
}
}
return true;
}
if(allAreTrue(true,true,$condition1,$condition2,false))
{
exit("Invalid Arguments");
}
//Continue
The best way to structure conditional logic is to follow the logic itself.
If you have dependencies, say, failing of first condition will make others unnecessary is one thing. Then return, goto, nested conditions and exceptions at your choice.
If you are about to make decision upon a test, say
if (!isset($_GET['id'])) {
//listing part:
} else {
// form displaying part:
}
it's else, elseif and case realm.
etc.
Determine your program logic first and write it's logic then.
and trigger_error() has nothing to do with conditions. It is debugging feature, not program logic related one.

Commenting code in PHP while using a framework

I'm creating a simple application using the Kohana PHP framework, just FYI. This is my first time with the framework.
While developing classes or functions I'm commenting my code using DocBlock. How should I comment my code while using the framework? I meant to code some parts of the code, not whole controllers.
Basically, I'm using following methods:
// Check if variable_name is greater than zero
if($this->var > 0) {
// do something
} else {
// do something
}
if( $result ) {
// display confirmation message
} else {
// display errors
}
Am I doing it right way? Is there a standard for inserting comments in the code?
I'm not using comments like "check if variable is greater than zero". I'm just wondering if is it good practice to put comments into the code.
Not related to visual style of the comments, but a comment like "Check if variable_name is greater than zero" is a bad comment in and by itself. All it does is duplicate the information on the line below. The code should contain names on variables, functions and other things that can be read to know what's going on.
Other than that, I see nothing wrong with the double-slash-comment types.
// Check if variable_name is greater than zero
Such comments are worthless. I only know little PHP, and even if I didn't knew anything about it, I could immediately tell (or at least, very confidently guess) that after looking at the line.
As a general (language-agnostic) rule of thumb, write code that is mostly self-documenting (by using descriptive names, avoiding non-obvious shortcuts, etc.) and only comment why you do something which looks wrong/strange.
Personally, I document inline sparingly (I do religiously put doc-blocks in for methods, classes and member variables though). I believe that code itself should be as self documenting as possible.
There will be times where you need to do something non-obvious or possibly even counter-intuitive. That's the time for inline comments. Try to explain not what the block of code does, but why it does it that way.
There's a great example in Phing's CodeCoverageReportTask class:
// Strange PHP5 reflection bug,
// classes without parent class or implemented interfaces
// seem to start one line off
if ($reflection->getParentClass() == NULL
&& count($reflection->getInterfaces()) == 0)
{
unset($coverageInformation[$classStartLine + 1]);
}
else
{
unset($coverageInformation[$classStartLine]);
}
And another good one just a few lines down from that:
// PHP5 reflection considers methods of a parent class to be part
// of a subclass, we don't
if ($method->getDeclaringClass()->getName() != $reflection->getName())
{
continue;
}
I completely agree that comments should never explain what the code does, only why. But, it is definitely good practice to put necessary comments into the code. When I go back and look over some of my code (PHP or other), I wish I had commented more clearly.
But, the only standard with comments is consistency! Be consistent and you don't have to worry so much about confusing comments (only about when to use them).
Some (if not most) PHP programmers use the double-slash method (//) for commenting their code. There really is no standard, and I've seen people who comment using the pound symbol (#) at the beginning of a line, and others who comment out blocks with /* and */.
Comments are liars!
The problem with comments is that you have to update them as you update your code. If you don't, you end up with code looking like this:
// sum $a and $b
$x = $a * $a - $b;
So the best way to document your code is to make it really clear! I would write your code like this:
if ( isPositive(3) ) {
doA();
} else {
doB();
}
if( $result ) {
displayConfirmationMsg();
} else {
displayErrors();
}
This code doesn't need comments at all, because it's very simple to understand it!
Well, anyway, when I do have to write comments (almost never), I go with the // notation, but I think it doesn't really matter.
By the way, check out this awesome video of Uncle Bob.

Categories