Zend comparison operation style - php

This may not be an important issue but it bugs me anytime(quite often) I come across it, so I need to put my mind to rest. Please bear with me.
I am more used to seeing and using comparison operations like this:
if($some_var ==NULL){}
But Zend documentation(and only in zend do I notice this) always reverses the operands:
if(NULL ==$some_var){}
I'm not a computer scientist, so I would like to know if the order of these operands matter. Is there a difference or reason why zend documentation chooses the reverse style?

The result is the same. The advantage of this approach is what happens if the programmer accidentally types one equals instead of two:
if ($some_var = NULL) // this will perform an assignment instead of a comparison
if (NULL = $some_var) // this will give you a parse error
so it helps prevent those kinds of coding mistakes.

I prefer to use the Zend style for one reason. If you accidentally type = instead of == or === you will get an error. In the variable-first format, you will silently assign that value to your variable.

Related

Comparison order in PHP IF

I'm pretty sure that there is no difference between this
if ($value === true)
and this
if (true === $value)
For me it always seems confusing. I used to think that it's a 'bad unconventional style of new developers'. Furthermore, my boss told me never to do such a thing.
But today I was looking through Slim's source code, written by the guy who created PHP: The Right Way, and saw this (line 341).
if (true === $value) {
$c['settings'] = array_merge_recursive($c['settings'], $name);
}
I'm sure a guy like Josh Lockhart wouldn't do something like this if it was considered a bad practice. So what's with this order? Is it some kind of an old tradition?
This is colloquially referred to as 'Yoda Conditions'. The reasoning behind their usage is because sometimes people make mistakes. In the context of an if statement, this is one such mistake that is sometimes made:
if($value = 42)
Notice there is no double equals sign (==). This is a valid statement and is not a syntax error. It is possible that it would cause huge disruptions with the code that follows it, and it is very hard to identify quickly. Yoda conditions get around this by reversing the conditional expression:
if(42 = $value)
This is not a valid statement and is a syntax error, and those are generally reported with a line number included, so they're pretty easy to find.
"Syntax error you have. Line 73 do something else you must." -- Yoda's compiler, probably
Whether or not you actually think they're good or bad is up to personal preference and style. In some cases of popular frameworks (such as Wordpress), Yoda conditions are actually part of the official coding standards. The major critique against them is that, to some, they decrease readability of the code without providing any real major benefit.
As #MonkeyZeus pointed out in a comment to the question, sometimes people do actually mean to only use a single equals sign inside of an if condition:
if($iMustHaveAValue = functionCallThatCanFail()) {
// Rest assured, $iMustHaveAValue has a truthy value.
}
Since the value of an assignment operation is the value assigned, the value that is evaluated by the if condition in this case (and in the original case which was unintended) is whatever value happened to be assigned.

Is it good practice to ignore non-fatal errors?

When I learned PHP I was taught to make my code error free, but to still hide errors in production code to ensure a clean user experience.
I've recently been involved in some projects where the original writer took the approach of leaving in errors and warnings and even utilizing them to achieve something, rather than write code without it.
For example, the code would look like this:
$numm = 0;
while($numm < 10){
$var = "something,".$var;
$numm++;
}
This code will throw a non-fatal Noticethe first time through the loop, because $var doesn't exist for the first concatenation.
There are tons of other examples where they either ignore errors, or even utilize them (to end loops, etc.) but then hide them from the user.
To me, this seems like bad practice, but I could just be OCD.
A Notice is a bug waiting to happen. I routinely run development with error_reporting(E_ALL); set. I want to find the bugs before they are a problem, and not simply ignore the problems, potential, or not.
Set a requirement of isset($var) in the while loop.
One thing that I have always found annoying was doing things like:
$var = isset($var) ? "something,".$var : "something,";
This one liner will prevent the error but not ideal way of doing it when you consider the number of possible uses. Imagine an associative array that returns that doesn't always have all it's key/values you would expect set.
One approach that i take to nearly all my apps is creating and using the following function:
function rtnVal(&$val, $default = null){
return isset($val) ? $val : $default;
}
so in this case, all I have to do is this:
$var = "something,".rtnVal($var);
Easy ain't it? In case you didn't know, defining
function rtnVal(&$var) { ... }
instead of:
function rtnVal($var) { ... }
(notice the & symbol) means that $var is a 'placeholder' (passed by reference) and not actually passed. So when you use it, it doesn't have to be previously set.
There is one limitation to this though and that's working with Objects, they don't like being passed by reference this way so for those, I have yet to find a better solution.

PHP # instead of isset to test a $_GET value

Give me one good reason to do this
if( isset($_GET['key']) && ($_GET['key'] === '123') )
{...
instead of this
if( #$_GET['key'] === '123' )
{...
I'm asking for this very specific code case, and not in general!
Following reasons are not welcome:
"using # will slow down the application by some nanoseconds because the
error is created anyway (even if it's supressed)." Well I prefer slower
code but more readable.
"using # is bad habit." It might be true in general, but I don't belive in this case (moreover bad habits might
depend on the context, on PHP manual in function like fopen they
suggest to use # in certain circumstainces, see Errors/Exceptions
at http://www.php.net/manual/en/function.fopen.php)
The performance impact isn't actually the best argument against this example and you would have to measure the performance in your own application to decide whether this is a problem. It is more likely to cause a slow down if a large number of items being checked are not set or if you placed a check such as this within a loop.
The main problem associated with using the # operator is that it is likely to become a convention in your code, so while your example may seem innocuous, you may later find yourself or your team using:
if( #IsAvailable() ) {
And the error suppression starts to hide real errors that you didn't anticipate as well as those that you did - and you have no idea what happened as you get no exception information at all.
Think about how much you could be slowing your application down when your website / app starts getting tens / hundreds of thousands (or more) of requests a day. If you're suppressing errors as a standard, you probably have dozens for every request - suddenly, you're site is noticeably slower than you would want it to be.
In addition to this, you could end up suppressing errors that you actually want to be aware of while developing.
If you don't take performance issue as argument, then it is indeed OK. But it does not has to be in all cases, because # will supress all possible errors, even those, you did not think about. But in this case, it seems there are not possible other errors that the one you want to supress.
I agree with you that preceed isset() before reading value is very ugly and I don't like to write it either. But insert # before statement seems ugly to mee to. It can decrease readibility in longer code.
Good news is, that since PHP 7 we can use much nicer way, null-coalescence operator ?? which works like this:
if($_GET['key'] ?? '' === '123' ) {}
It is basically replacement for this:
$result = isset($value) ? $value : $anotherValue;
now you can use
$result = $value ?? $anotherValue;

Clarity of using if(count())

In this code fragment:
$results = $this->getAdapter()->fetchAll($query);
if(count($results)) {
// …
}
…do you consider the if(count()) part to be be a well understood idiom, or confusing code. i.e. should it be
if(count($results) > 0)
???
Using a boolean expression with 'if' requires less understanding of a language than using implicit conversions, so I would always prefer the second option (adding "> 0") - at least if this code is meant to be read by others, too. You never know who will maintain your code. The keyword is "clarity" here.
But I must admit I have written many times code with if's using an int expression myself, too, because I like its elegance.
They are doing exactly the same job in this context, and are both easily readable.
I'll just add (just in case) that if you're performing this query only to if(count()), then you should be issuing a SELECT COUNT(*) instead!
The count and the extraneous > comparison are pointless. If you receive an actualy array, then the test should just be:
if ($results) {
That's what scripting languages are for. Abstracting low level details away.
You would only need the count if your fetchAll function returns an ArrayObject or similar. Should your function sometimes return a false for example, then your if (count( is going to fail (because count(false)==1 in PHP).
erm...not realy sure what the purpose of this question is - but the semantics should be self-evident to anyone whom understands PHP
My opinion is that the > 0 check is redundant and unnecessary.
I know other developers who insist that it should be there for clarity, but frankly I can't why -- anyone who can read PHP should be able to discern that they are identical.

Is #$array['possibly_missing_key'] an anti-pattern?

Is it OK to use # when extracting a possibly missing value from a PHP array? Example:
$value = #$array['possibly_missing_key'];
The intended behavior:
if (isset($array['possibly_missing_key'])) {
$value = $array['possibly_missing_key'];
} else {
$value = null;
}
I want to know, before spreading the usage pattern.
The # operator suppresses error messages, and using it potentially sets up your code for other errors and unexpected behavior that end up hard to track down. Thus it's most certainly an antipattern.
Thus, I would very much prefer the second bit. It makes it much clearer
that it may not be present in the array, and
what the default value is if it's not present
To make it more concise you can use the ternary conditional operator ?:, as seen in Mark Baker's answer. Slightly less code and more symbols but the meaning is well-recognized.
Actually the isset variation is the anti-pattern. If you just use isset($var)?$var:NULL with the intention to suppress the "error", then you've achieved nothing over using the proper syntax for suppressing errors. It has the same outcome, yet is less readable.
People are arguing for that because of perceived "cleanliness" and because using isset is a micro optimization. Avoiding # and using isset as syntactic salt replacement is just cargo cult programming.
Or
$value = (isset($array['possibly_missing_key'])) ? $array['possibly_missing_key']: null;
Ignoring warnings is definitely an antipattern; so yes, it's an anti-pattern (and I can guarantee that if you learn to suppress warnings, one of them will come back and bite you in the posterior, if not worse).
Also, while the second version is more verbose, it gives the uninitialized variable a known state (or can be used to handle the problem, if the variable is supposed to be filled).
The third option:
$value = (isset($array['key']) ? $array['key'] : null);
I know this doesn't directly answer the question; I would have put it as a comment, except it really needed to be formatted.
The idea here is that if you're trying to make your code shorter by using a one-liner instead of an if-else block, then you can still get it into a succinct one-liner using a ternary operator, giving you the best of both worlds.
The second block of code (or Mark Baker's alternative which will work exactly the same) is better. I'm not entirely sure about PHP, but in many other programming languages, to simply ignore a variable would almost definitely throw an error. At least with the second block you are initializing the variable to some value or memory location.
Error suppression should be more commonly used if you expect a function to throw an expected error in the end-product (however, much of the time this will not be the case).
Good luck!
Dennis M.

Categories