Есть ли разница между $ str == '' и strlen ($ str) == 0 в PHP? - PullRequest
6 голосов
/ 19 декабря 2008

Как видно из заголовка: есть ли разница между $ str == '' и strlen ($ str) == 0 в PHP? Есть ли какая-то реальная разница в скорости, и лучше ли использовать одну из них?

Ответы [ 11 ]

17 голосов
/ 19 декабря 2008

мне кажется, проще сделать "if (! $ str)" .. не уверен насчет '==', но '!' должен быть в состоянии привести к лучшим методам оптимизации, так как никогда не выполняется типизация, и он безопасен для строк, массивов, bools, чисел ...

11 голосов
/ 19 декабря 2008

Да, есть важное различие. Оператор == делает преобразование типов , поэтому он не всегда будет делать то, что вы ожидаете. Например, (0 == "") возвращает true. Итак, вы предполагаете, что $ str на самом деле является строкой. Если вы уверены, что это так, или если вы не заботитесь о конверсиях, тогда это нормально. В противном случае вы должны использовать === и предпринять шаги, чтобы убедиться, что вы сравниваете строки.

10 голосов
/ 19 декабря 2008

Основное отличие состоит в том, что $ str == '' будет возвращать true для всего, что эквивалентно пустой строке (0 и false, среди других ).

Вы должны использовать либо оператор === для проверки на наличие реальной пустой строки, либо, если вы не возражаете против преобразования и тестирования поведения, просто используйте! $ 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)
7 голосов
/ 19 декабря 2008

Я выполнил простой тест. (Я никогда не делал ни одного, поэтому это может быть совершенно недопустимым.) Он проверяет == '', 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

Как видите, сравнение с '' вдвое быстрее, чем сравнение длины строки. Кроме того, использование === немного быстрее, чем использование ==, и это безопасно для типов! Ницца.

4 голосов
/ 19 декабря 2008

Даже если бы была разница в скорости, вы не должны выбирать более быструю. Выберите более ясный вариант.

1 голос
/ 19 декабря 2008

Нет, они не одинаковы (как описано выше), но для ваших целей они могут быть взаимозаменяемыми.

Быстрее? В качественном отношении трудно представить ситуацию, в которой разница в любом случае будет существенной, но можно увидеть другие более количественные ответы. Кодирование, основанное на скорости, здесь, вероятно, является примером нашего любимого уничижительного выражения, которое может быть сокращено до «пи».

Что лучше?

Это зависит от того, какое утверждение о $ str вы хотите подтвердить, и какие последствия вы хотите вызвать.

Другой распространенный шаблон, который вы увидите, -

! $ * Ул 1011 *

, который в целом дает тот же результат - и может быть уместным, если вы просто хотите проверить строковое значение, которое непригодно для использования, независимо от того, почему оно непригодно - это может быть отсутствие инициализации, инициализация по умолчанию, назначение и т. Д. Я не спорю за или против этого представления, кстати.) Помните, что то, что вы решите, предположительно будет иметь последствия, и вам нужно понять, какие состояния $ str вызывают какие последствия, основываясь на том, как вы написали код. (И обратите внимание, что есть значения / состояния $ str, которые вы, возможно, не указали явно ни в одном из наших вариантов.)

1 голос
/ 19 декабря 2008

При выполнении $str=='' могут возникнуть проблемы с преобразованием типов. Например, рассмотрим случаи, когда $str равно false (логическое значение) или 0 (целое число). Они могут просто выйти равными. Я не совсем уверен в этом, так что вы должны немного обдумать это. Безопасным способом было бы сделать $str===''.

1 голос
/ 19 декабря 2008

strlen ($ str) == 0 требует вызова strlen и вызова для сравнения. $ str == '' это просто сравнение.

1 голос
/ 19 декабря 2008

Может быть:! Strlen ($ str)

1 голос
/ 19 декабря 2008

Разница в скорости слишком мала, чтобы иметь значение, я уверен. Лучший метод для использования - более читаемый. Вот две другие альтернативы:

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

if (!$str) {
    ...
}

Примечание: Они оба будут иметь значение true, если $ str == '0'.

...