As the title says: Is there a difference between $str == '' and strlen($str) == 0 in PHP? Is there any real speed difference and is one better to use than the other?
$str == '' is better practice. There probably isn't much difference in PHP, since it knows the length of its strings, but it'd be a really bad habit to have if you then went and did some work in a lower-level language.
The speed difference is too small to matter, I'm sure. The best method to use is the more readable one. Here are two other alternatives:
if (empty($str)) {
...
}
if (!$str) {
...
}
Note: These will both evaluate to true if $str == '0'.
strlen($str) == 0 requires a call to strlen and a call to do the comparison. $str == '' is just a comparison.
There might be some type-conversion issues when doing $str==''
. For example, consider cases when $str
is false
(boolean) or 0
(integer). They might just come out equal too. I'm not exactly sure about this, so you should muck around with it a bit. The safe way would be to do $str===''
.
Even if there was a speed difference, you should not pick the faster one. Pick the clearer one.
Yes, there is an important difference. The == operator does type conversion, so it's not always going to do what you expect. For example, (0 == "") returns true. So you're making an assumption that $str is actually a string. If you're sure this is the case, or if you don't care about the conversions, then it's fine. Otherwise you should use ===, and take steps to ensure that you're comparing strings.
The main difference is that $str == '' will return true for anything that's equivalent to the empty string (0 and false, among others).
You should use either the === operator to test for an actual empty string or, if you don't mind the convert and test behavior, just use !$str (consider empty() as well, depending on the actual intent), which I find clearer in intent than $x == '' (Did he miss an = sign and actually wants to test for an empty string?.)
Use strlen($str) only when you really are after the length of a string.
Bottom line, use the proper tool for the job, judging which tool is proper based on the intent of the code.
vinko@parrot:~$ cat emptytest.php
<?php
$a = "";
$b = 0;
$c = false;
$d = "Hi!";
function is_empty1($x) { return $x == ''; }
function is_empty2($x) { return strlen($x) == 0; }
function is_empty3($x) { return $x === ''; }
function check_empty($arr) {
foreach ($arr as $v) {
echo "value is ";
var_dump($v);
echo " \$x == '' ";
var_dump(is_empty1($v));
echo " strlen($x) == 0 ";
var_dump(is_empty2($v));
echo " \$x === '' ";
var_dump(is_empty3($v));
}
}
check_empty(array($a,$b,$c,$d));
?>
vinko@parrot:~$ php emptytest.php
value is string(0) ""
$x == '' bool(true)
strlen() == 0 bool(true)
$x === '' bool(true)
value is int(0)
$x == '' bool(true)
strlen() == 0 bool(false)
$x === '' bool(false)
value is bool(false)
$x == '' bool(true)
strlen() == 0 bool(true)
$x === '' bool(false)
value is string(3) "Hi!"
$x == '' bool(false)
strlen() == 0 bool(false)
$x === '' bool(false)
I performed a simple benchmark. (I've never done one so this may be completely invalid.) It tests == '', strlen() == 0, === '', and strlen() === 0.
header('Content-type: text/plain');
// -- Testing == '';
$string = '';
$startTime = microtime(true);
for($i = 0; $i < 10000000; ++$i)
$string == '';
$endTime = microtime(true);
echo "\$string = ''; \$string == ''; took " . ($endTime - $startTime) . " seconds\n";
$string = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
$startTime = microtime(true);
for($i = 0; $i < 10000000; ++$i)
$string == '';
$endTime = microtime(true);
echo "\$string = '$string'; \$string == ''; took " . ($endTime - $startTime) . " seconds\n";
$startTime = microtime(true);
for($i = 0; $i < 10000000; ++$i)
'' == '';
$endTime = microtime(true);
echo "'' == ''; took " . ($endTime - $startTime) . " seconds\n";
// -- Testing strlen() == 0;
$string = '';
$startTime = microtime(true);
for($i = 0; $i < 10000000; ++$i)
strlen($string) == 0;
$endTime = microtime(true);
echo "\$string = ''; strlen(\$string) == 0; took " . ($endTime - $startTime) . " seconds\n";
$string = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
$startTime = microtime(true);
for($i = 0; $i < 10000000; ++$i)
strlen($string) == 0;
$endTime = microtime(true);
echo "\$string = '$string'; strlen(\$string) == 0; took " . ($endTime - $startTime) . " seconds\n";
$startTime = microtime(true);
for($i = 0; $i < 10000000; ++$i)
strlen('') == 0;
$endTime = microtime(true);
echo "strlen('') == ''; took " . ($endTime - $startTime) . " seconds\n";
// -- Testing === '';
$string = '';
$startTime = microtime(true);
for($i = 0; $i < 10000000; ++$i)
$string === '';
$endTime = microtime(true);
echo "\$string = ''; \$string === ''; took " . ($endTime - $startTime) . " seconds\n";
$string = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
$startTime = microtime(true);
for($i = 0; $i < 10000000; ++$i)
$string === '';
$endTime = microtime(true);
echo "\$string = '$string'; \$string === ''; took " . ($endTime - $startTime) . " seconds\n";
$startTime = microtime(true);
for($i = 0; $i < 10000000; ++$i)
'' === '';
$endTime = microtime(true);
echo "'' === ''; took " . ($endTime - $startTime) . " seconds\n";
// -- Testing strlen() === 0;
$string = '';
$startTime = microtime(true);
for($i = 0; $i < 10000000; ++$i)
strlen($string) === 0;
$endTime = microtime(true);
echo "\$string = ''; strlen(\$string) === 0; took " . ($endTime - $startTime) . " seconds\n";
$string = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
$startTime = microtime(true);
for($i = 0; $i < 10000000; ++$i)
strlen($string) === 0;
$endTime = microtime(true);
echo "\$string = '$string'; strlen(\$string) === 0; took " . ($endTime - $startTime) . " seconds\n";
$startTime = microtime(true);
for($i = 0; $i < 10000000; ++$i)
strlen('') === 0;
$endTime = microtime(true);
echo "strlen('') === ''; took " . ($endTime - $startTime) . " seconds\n";
Results:
$string = ''; $string == ''; took 1.01983308792 seconds
$string = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; $string == ''; took 1.04193401337 seconds
'' == ''; took 1.06608295441 seconds
$string = ''; strlen($string) == 0; took 2.1510848999 seconds
$string = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; strlen($string) == 0; took 2.27101397514 seconds
strlen('') == ''; took 2.5775551796 seconds
$string = ''; $string === ''; took 0.854554176331 seconds
$string = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; $string === ''; took 0.714010000229 seconds
'' === ''; took 0.749495983124 seconds
$string = ''; strlen($string) === 0; took 1.9263010025 seconds
$string = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; strlen($string) === 0; took 1.95309996605 seconds
strlen('') === ''; took 2.40874910355 seconds
As you can see, comparing to '' is about twice as fast as comparing the length of the string. Also, using === is slightly faster than using ==, and it's type safe! Nice.
No, they're not the same (as explained above), but for your purposes they might be interchangeable.
Faster? Qualitatively, it's hard to imagine a situation where the difference either way would be consequential, but see other more quantitative answers. Coding based on speed here is probably an example of our favorite pejorative, which can be abbrevated "pi".
Which is best?
It depends on what assertion about $str you want to confirm, and what consequence you want to invoke.
Another common pattern you'll see is
!$str
which gives generally the same result - and may be appropriate if you simply want to test for a string value that is unusable, no matter why it's unusable - which could be lack of initialization, initialization default, assignment, etc. (I'm not arguing for or against this representation, BTW.) Remember that what you decide will presumably have consequences, and you need to understand what $str states invoke which consequences, based on the way you've written the code. (And notice there are $str value/states which you might not have explicitly covered with either of our options.)
i find it clearer to just do "if (!$str)" .. not sure about '==' but '!' should be able to yeld better optimization techniques, as no typecasting is ever done, and is safe for strings, arrays, bools, numbers...