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'
Related
The triple equal I think everyone understands; my doubts are about the double equal. Please read the code below.
<?php
//function to improve readability
function compare($a,$b,$rep)
{
if($a == $b)
echo "$rep is true<br>";
else
echo "$rep is false<br>";
}
echo "this makes sense to me<br>";
compare(NULL,0,'NULL==0');
compare(NULL,"",'NULL==""');
compare(NULL,[],'NULL==[]');
compare(0,"",'0==""');
echo "now this is what I don't understand<br>";
compare("",[],'""==[]');
compare(0,[],'0==[]');
compare(0,"foo",'0=="foo"');
echo "if I cast to boolean then it makes sense again<br>";
compare("",(bool)[],'""==(bool)[]');
compare(0,(bool)[],'0==(bool)[]');
?>
Output:
this makes sense to me
NULL==0 is true
NULL=="" is true
NULL==[] is true
0=="" is true
now this is what I don't understand
""==[] is false
0==[] is false
0=="foo" is true
if I cast to boolean then it makes sense again
""==(bool)[] is true
0==(bool)[] is true
I would expect an empty array to be "equal" to an empty string or to the integer 0. And I wouldn't expect that the integer 0 would be "equal" to the string "foo". To be honest, I am not really understanding what PHP is doing behind the scenes. Can someone please explain to me what is going on here?
The simple answer is that this is the way php has been designed to work.
The outcomes are well defined in the docs comparison operators and comparison tables.
A == comparison between an array (your first two queries) and a string always results in false.
In a == comparison between a number and a string (your third query) the string is converted to a number and then a numeric comparison made. In the case of 0=='foo' the string 'foo' evaluates numerically to 0 and the test becomes 0==0 and returns true. If the string had been 'numeric' e.g. "3" then the result in your case would be false (0 not equal to 3).
Whether the design is "correct" (whatever that may mean) is arguable. It is certainly not always immediately obvious. An illustrative example of the potential fury of the debate can be found in Bug#54547 where the devs argue strongly that the design is rooted in php's history as a web language where everything is a string and should be left alone, and others argue php "violates the principle of least surprise".
To avoid uncertainty use === wherever possible, with the added benefit of potentially showing up assumptions in your code that may not be valid.
As someone has already said, the PHP automatic casting rules can be quite tricky, and it is worth using === unless you know both sides will be of the same type. However I believe I can explain this one:
""==[] (returns false)
The initial string "" indicates the comparison will be a string one, and thus [] is cast to a string. When that happens, the right hand side of the comparison will be set to the word Array. You are therefore doing this comparison:
"" == "Array" (returns false)
and thus false is the correct result.
Edit: a helpful comment below casts doubt on my answer via this live code example. I should be interested to see what other answers are supplied.
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
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.
I know that for instance, using:
if (in_array('...'), array('.', '..', '...') === true)
Over:
if (in_array('...'), array('.', '..', '...') == true)
Can increase performance and avoid some common mistakes (such as 1 == true), however I'm wondering if there is a reason to use strict comparisons on strings, such as:
if ('...' === '...')
Seems to do the exactly same thing as:
if ('...' == '...')
If someone can bring some light to this subject I appreciate it.
If you know both of the values are guaranteed to be strings, then == and === are identical since the only difference between the two is that === checks to see if the types are the same, not just the effective values.
However, in some cases you don't know for sure that a value is going to be a string - for example, with things like the $_GET and $_POST variables. Consider the following:
$_GET['foo'] == ""
The above expression will evaluate to true if foo was passed in as a blank string, but it will also evaluate to true if no value was passed in for foo at all. In contrast,
$_GET['foo'] === ""
will only evaluate to true if a blank string was explicitly passed in - otherwise the value of $_GET['foo'] might be equivalent to a blank string, but the type would not be since it would actually be an empty value for that index, not a string.
When you can use one or the other choose the strict comparison because:
It has better performance
It prevents unexpected results
When comparing strings you can still have unexpected results because a string could be empty or a variable you think is a string actually is not.
You would never use the comparison of two string literals because it can always be reduced to TRUE or FALSE. For example:
if ('...' === '...')
is the same as
if (TRUE)
So since you will always be comparing at least one variable you must assume that you can have unexpected results.
You can see benchmark results of various strict vs. loose comparisons at http://net-beta.net/ubench/. I have also ran my own tests and found the same results.
This is a micro optimization, which means you shouldn't go changing existing code because it isn't going to make a noticeable difference, but if you are writing new code you might as well practice using the most efficient techniques.
Summarized, I made a loop with a few iterations to check the efficiency of each test:
$iterations = 99999999;
$var = null;
isset comparasion
if ( isset( $var ) )
{
}
'===' comparasion
if ( $var === null )
{
}
And i have this log, in microseconds:
'isset()': 1.4792940616608
'===': 1.9428749084473
For me, this is a little curious. Why isset() function is faster than one comparison operator as ===?
The === comparison is a strict check, meaning that the two objects you're comparing have to be of the same type. When you break it down in plain English, it's actually not that weird that === needs some more time. Consider the parser to do this:
if (isset($var)) {
// Do I have something called $var stored in memory?
// Why yes, I do.. good, return true!
}
if ($var === null) {
// Do I have something called $var stored in memory?
// Why yes, I do.. good! But is it a NULL type?
// Yes, it is! Good, return true!
}
As you can see, the === operator needs to do an additional check before it can determine if the variable matches the condition, so it's not that strange that it is a little bit slower.
Isset is not a function: it is a language built-in. Using isset is faster than using a function.
The other thing is that isset is used all over the place, so it makes sense that it's been profiled to death, whereas === maybe hasn't received as much love.
Other than that, you'd have to dig in the PHP source with a profiler to see exactly what's going on.
I'm not sure I would call 100 million "a few iterations". You appear to have accumulated about a half-second difference, divide that by 100 million and you get a whopping 5 nanosecond difference per iteration if my math is correct. With the difference being so small it may simply come down to the fact that isset only has one operand in this context and === has two.
It's impossible to even discuss the Zend engine's implementation details of the two examples without specifying a specific PHP version; source code is a moving target. Even minute changes to the implementations are going to effect the results over that many passes. I would not be surprised if you found the opposite to be the case on some versions of PHP and/or in a different context.
isset itself is covered by three different op-codes in the VM depending upon the context:
"Simple" Compiled Variables like your example: ZEND_ISSET_ISEMPTY_VAR
Arrays: ZEND_ISSET_ISEMPTY_DIM_OBJ (requires 2 operands, the var and the index)
Object properties: ZEND_ISSET_ISEMPTY_PROP_OBJ (also 2 operands, var and prop name)
It's an interesting question for curiosity's sake but we're in hair splitting territory and it's probably not a real-world optimization strategy.