【问题标题】:Is there a difference between $str == '' and strlen($str) == 0 in PHP?PHP 中的 $str == '' 和 strlen($str) == 0 有区别吗?
【发布时间】:2010-09-27 18:32:18
【问题描述】:

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

【问题讨论】:

    标签: php strlen


    【解决方案1】:

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

    您应该使用 === 运算符来测试实际的空字符串,或者,如果您不介意转换和测试行为,只需使用 !$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)
    

    【讨论】:

    • 如果 $x 为 false 并且您调用 strlen($x),$x 将被转换为空字符串,其长度将为 0。strlen($x) == 0 不等于===。如果这是您想要的行为,请使用 ===。
    • 是的。删除了那个例子。那些“真的真的平等”和“不太平等但平等”的运营商充其量是烦人的。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      哪个最好?

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

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

      !$str

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 我喜欢前两个结果。我的回答说 strlen($x) == 0 是两个操作, $str == 0 是一个操作。感谢您确认两个操作所需的时间大约是一个操作的两倍。 :-)
        【解决方案5】:

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

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

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

        【讨论】:

        • 这些例子不正确。 empty('0') == empty('') 为真
        • 是的,和 '!$str' 一样,但这几乎总是适用于我正在编写的代码。
        • 是的,但这是一个应该给出正确答案的地方。不是几乎总是在您编写的代码中起作用的答案。
        • 如果字符串没有数据,不要使用 Empty 进行比较。你有坏习惯。
        【解决方案6】:

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

        【讨论】:

        • strlen($str) 也会进行类型转换。有时它也不符合您的预期。
        • 可能值得注意的是 === 是 PHP5 的一项功能(仍然有 PHP4 代码/项目)。
        • === 运算符不是 php5 独有的功能。它是 us3.php.net/language.operators.comparison">introduced in PHP4
        【解决方案7】:

        即使存在速度差异,您也不应选择较快的。选择更清晰的。

        【讨论】:

        • 你的意思是“更清晰”,更容易被人类理解吗?
        • @ryanve 是的,这就是我的意思
        【解决方案8】:

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

        【讨论】:

        • 调用 strlen(false) 或 strlen(0) 时也会发生类型转换。如果 $str 为假,则 false == '' 为真。 false === '' 是假的。
        【解决方案9】:

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

        【讨论】:

          【解决方案10】:

          也许:!strlen($str)

          【讨论】:

            【解决方案11】:

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

            【讨论】:

              猜你喜欢
              • 2020-11-09
              • 2021-12-08
              • 2012-01-09
              • 2015-07-17
              • 1970-01-01
              • 2017-06-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多