7

正如标题所说: PHP 中的 $str == '' 和 strlen($str) == 0 有区别吗?是否有任何真正的速度差异,一个比另一个更好用?

4

11 回答 11

17

我发现只做 "if (!$str)" 更清楚.. 不确定 '==' 但 '!' 应该能够产生更好的优化技术,因为没有进行过类型转换,并且对于字符串、数组、布尔值、数字是安全的......

于 2008-12-19T20:21:32.320 回答
11

是的,有一个重要的区别。== 运算符会进行类型转换,因此它并不总是按照您的预期进行。例如,(0 == "") 返回 true。所以你假设 $str 实际上是一个字符串。如果您确定是这种情况,或者您不关心转换,那没关系。否则,您应该使用 ===,并采取措施确保您正在比较字符串。

于 2008-12-19T19:36:14.627 回答
10

主要区别在于 $str == '' 对于任何与空字符串等效的内容(0 和 false)都将返回 true。

您应该使用 === 运算符来测试实际的空字符串,或者,如果您不介意转换和测试行为,只需使用 !$str (也可以考虑empty(),具体取决于实际意图),我发现它的意图比 $x == '' 更清晰(他是否错过了 = 符号并且实际上想要测试一个空字符串?)

仅当您确实在字符串长度之后才使用 strlen($str)。

最重要的是,为工作使用合适的工具,根据代码的意图判断哪个工具是合适的。

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)
于 2008-12-19T19:37:13.613 回答
7

我执行了一个简单的基准测试。(我从未做过,所以这可能完全无效。)它测试 == ''、strlen() == 0、=== '' 和 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";

结果:

$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

如您所见,与 '' 进行比较的速度大约是比较字符串长度的两倍。此外,使用 === 比使用 == 稍快,而且它是类型安全的!好的。

于 2008-12-19T19:40:07.927 回答
4

即使存在速度差异,也不应选择速度较快的。选一个比较清楚的。

于 2008-12-19T19:33:43.603 回答
1

$str == '' 是更好的做法。PHP 可能没有太大区别,因为它知道其字符串的长度,但是如果您随后使用较低级别的语言进行一些工作,那将是一个非常糟糕的习惯。

于 2008-12-19T19:29:04.720 回答
1

我敢肯定,速度差异太小了。最好的使用方法是可读性更强的方法。以下是另外两种选择:

if (empty($str)) {
    ...
}

if (!$str) {
    ...
}

注意:如果 $str == '0',这些都将评估为 true。

于 2008-12-19T19:30:33.190 回答
1

也许: !strlen($str)

于 2008-12-19T19:31:12.470 回答
1

strlen($str) == 0 需要调用 strlen 并调用进行比较。$str == '' 只是一个比较。

于 2008-12-19T19:31:17.087 回答
1

执行时可能会出现一些类型转换问题$str==''。例如,考虑$stris false(boolean) 或0(integer) 的情况。他们也可能是平等的。我不太确定这一点,所以你应该稍微考虑一下。安全的方法是这样做$str===''

于 2008-12-19T19:33:16.520 回答
1

不,它们不一样(如上所述),但出于您的目的,它们可能是可以互换的。

快点?定性地说,很难想象任何一种方式的差异都会产生影响的情况,但可以看到其他更定量的答案。这里基于速度的编码可能是我们最喜欢的贬义词的一个例子,可以缩写为“pi”。

哪个最好?

这取决于您要确认的有关 $str 的断言,以及您要调用的结果。

您会看到的另一个常见模式是

!$str

这通常给出相同的结果 - 如果您只是想测试一个不可用的字符串值,无论它为什么不可用 - 这可能是合适的 - 这可能是缺乏初始化,初始化默认值,赋值等。(我不是支持或反对这种表示,顺便说一句。)请记住,您的决定可能会产生后果,并且您需要根据您编写代码的方式了解 $str 状态调用哪些后果。(请注意,我们的任何一个选项都可能没有明确涵盖 $str 值/状态。)

于 2008-12-19T20:04:35.897 回答