Is it safe to always use === in PHP? - php

I'm new to PHP and I just ran across a day-wasting bug because I didn't realize that the PHP == operator does type coercion similar to Javascript.
I know that Douglas Crockford recommends never using the == operator with Javascript, and to always use the === operator.
If I code in a manner that never assumes type coercion, can I use the same advice in PHP, and never use the == operator? is it safe to always use the === operator, or are there gotchas that I need to be aware of?

You should use === by default (to avoid the problems you just encountered) and use == when needed, as a convenience.
For instance, you may be taking parameters from $_GET or similar, and a parameter might be the string true or false, vs the boolean true or false. Personally, I check everything, but there can be legitimate use cases for == if you are conscious of it, and careful with use.

== and ===, exist for specific reasons. As you've already mentioned in your post, == does type coercion.
I come from a strongly typed programming background, and thus never require type coercion, quite like you. In this case, it is safe to always use ===.
Of course, when you do require coercion, use ==.
In case of inputs you have no control over (GET/POST parameters, API responses) you could either use == or use casting.

var_dump('1' == 1); return bool(true) and var_dump('1' === 1); return bool(false) because they have the same value but different types. One is string and other is int.
Only use === if you know the type you are checking.

Related

Should one use `if ($a != NULL)` or `if ($a !== NULL)` to control program flow?

This is perhaps a painfully basic question to answer, but I'm wondering about performance issues regarding using PHP's if identical !== versus if equal != to control flow.
Consider the following trivial PHP function:
<?php
function test_json($json = NULL) {
if ($json != NULL) {
echo 'You passed some JSON.';
} else {
echo 'You failed to pass any JSON.';
}
}
?>
From a performance standpoint, is it preferable to employ if identical (!==) to prevent PHP iterating through variable types, attempting to find a valid comparison?
I assume that !== first compares the variable types, and if that fails, it immediately returns FALSE?
I've used != since PHP3 almost as a reflex. Now that I'm working on some much more computationally-intensive projects, minute performance considerations become more of a concern.
Other comments on flow control optimization are, of course, welcome!
I haven't done any performance tests on loose vs strict comparison operators, but for what you are trying to do, I would instead recommend something like
if (!is_null($json)) {
do_stuff()
}
More information on is_null() at http://www.php.net/manual/en/function.is-null.php
EDIT: a note in the comments of the php page I linked to above has some results showing that the === operator is slightly faster than the == operator, both of which are faster than is_null(). However, another note points out that "The execution time difference between ===NULL and is_null is less than 250 nanoseconds. Go optimize something that matters." I'd have to agree there. So all that said, I would suggest you go with what you deem to be the most readable.
You could write a test code like this before asking; according to test "Using "===" is 30x quicker than is_null()."
http://www.php.net/manual/en/language.types.null.php#77937

identity conditional "===" , performance, and conversion

I've always came away from stackoverflow answers and any reading I've done that "===" is superior to "==" because uses a more strict comparison, and you do not waste resources converting value types in order to check for a match.
I may be coming at this with the wrong assumption, so I assume part of this question is, "is my assumption true?"
Secondly,
I'm dealing specifically with a situation where I'm getting data from a database in the form of a string "100".
The code I am comparing is this...
if ($this->the_user->group == 100) //admin
{
Response::redirect('admin/home');
}
else // other
{
Response::redirect('user/home');
}
vs.
if ( (int) $this->the_user->group === 100) //admin
{
Response::redirect('admin/home');
}
else // other
{
Response::redirect('user/home');
}
or even
if (intval($this->the_user->group) === 100) //admin
{
Response::redirect('admin/home');
}
else // other
{
Response::redirect('user/home');
}
is any integrity (or performance) gained by manually casting or converting simply so you can use the identity ('===') comparison?
In your particular case == is the better option. As you (as can be seen in your code) have probably already found out many database functions will always return strings, even if you fetch an integer. So type strict comparison really only bloats your code.
Furthermore you are adding a potential (let's call it theoretic) security risk. E.g. (int) '100AB2' would yield 100. In your case this probably can't happen, but in others it may.
So: Don't overuse strict comparison, it's not always good. You mainly need it only in ambiguous cases, like the return value of strpos.
There is a performance difference between == and === - latter will be even twice as fast, see Equal vs identical comparison operator.
The difference, however is too small to be bothered with - unless the code is executed millions of times.
That's a really tiny optimization you're doing there. Personally, I don't think it's really worth it.
Any boost you gain from not casting the value when using === is lost when you explicitly cast the value. In your case, since the type is not important to you, you should just do == and be done with it.
My recommendation would be to keep === for when you need to check type as well - e.g. 0 evaluating to false and so on.
Any performance gains will be microscopically small, unless you're performing literally billions and trillions of these comparisons for days/months/years on-end. The strict comparison does have its uses, but it also is somewhat of anomally in PHP. PHP's a weakly typed language, and (usually) does the right thing for auto-converting/casting values to be the right thing. Most times, it's not necessary to do a strict comparison, as PHP will do the right thing.
But there are cases, such as when using strpos, where the auto-conversion will fail. strpos will return '0' if the needle you're searching is right at the start of the haystack, which would get treated as FALSE, which is wrong. The only way to handle this is via the strict comparison.
PHP has some WTF loose comparisons that return TRUE like:
array() == NULL
0 == 'Non-numeric string'
Always use strict comparison between a variable and a string
$var === 'string'

== and === operators in php

Let's say I have a variable that will always be a string.
Now take the code below:
if($myVar === "teststring")
Note: $myVar will always be a string, so my questions is
Which is quicker/best, using === (indentity) or the == (equality)?
Testing for identity is always faster, because PHP does not have to Type Juggle to evaluate the comparison. However, I'd say the speed difference is in the realms of nanoseconds and totally neglectable.
Related reading:
PHP type comparison tables
Type Juggling
=== will be slightly faster, but more importantly, It enforces that $myVar will be a string so you don't have to worry about the possible effects of it being some other type.
In general when I code, I use == over ===, however, using the identity is more precise, and also, slightly faster (difference is minimal).
The difference between the two is likely irrelevant for whatever you need.

php boolean help

I seem to have a small problem, in the code below $a_trip is always true, even if $trip!= $admin_trip. Any idea why?
if($trip == $admin_trip)
$a_trip = true;
if($a_trip == true)
$trip = ("~::##Admin##::~");
In PHP, strings and numbers other than zero will evaluate as true. Make sure that $a_trip is false or empty, or use the equality operator that evaluates type:
if($a_trip === true)
PHP's normal equality is very lax, and considers many values to be the same even when types are different.
Beat me to it. === means 'identical'.
Check this out.
http://php.net/manual/en/language.operators.comparison.php
Also a sidenote, you should use { } in your if statements. You'll thank yourself later when debugging. It's easier to read.

How can I have PHP avoid lazy evaluation?

I have an interesting question about the way PHP evaluates boolean expressions. When you have, for example,
$expression = $expression1 and $expression2;
or
if ($expression1 and $expression2)
PHP first checks if $expression1 evaluates to true. If this is not the case, then $expression2 is simply skipped to avoid unnecessary calculations. In a script I am writing, I have:
if ($validator->valid("title") and $validator->valid("text"))
I need to have the second statement ($validator->valid("text")) evaluated even if the first one evaluates to false. I would like to ask you whether there is some easy way to force PHP to always evaluate both statements. Thank you!
$isValidTitle = $validator->valid("title");
$isValidText = $validator->valid("text");
if($isValidTitle && $isValidText)
{
...
}
Will that suit?
This is known as short circuit evaluation, and to avoid it you need to do this, using a single &:
if($validator->valid("title") & $validator->valid("text")) {
}
Note that this is not using logical operators but actually bitwise operators:
They're operators that act on the binary representations of numbers. They do not take logical values (i.e., "true" or "false") as arguments without first converting them to the numbers 1 and 0 respectively. Nor do they return logical values, but numbers. Sure, you can later treat those numbers as though they were logical values (in which case 0 is cast to "false" and anything else is cast to "true"), but that's a consequence of PHP's type casting rules, and nothing to do with the behavior of the operators.
As such, there is some debate as to whether it is good practice to use this side effect to circumvent short-circuit evaluation. I would personally at least put a comment that the & is intentional, but if you want to be as pure as possible you should evaluate whether they are valid first and then do the if.
try to evaluate each term separately:
$term1 = $validator->valid("title");
$term2 = $validator->valid("text");
if($term1 && $term2) {
//things to do
}
This might not be the best implementation, but you could always do:
$a=$validator->valid("title");
$b=$validator->valid("text");
if($a && $b) {...}
You can define a function like:
function logical_and($x,$y) {return ($x && $y);}
Since PHP uses call-by-value, this works.
Alternatively, if you can modify the class $validator instantiates, you could make the valid method accept a string or an array. If it's an array, it runs the code that already exists on each item and only returns TRUE if all items are "valid".

Categories