Я заметил, что многие разработчики используют как strstr, так и strpos для проверки существования подстроки. Какой из них предпочтительнее и почему?
Ответы:
Из онлайн-руководства PHP :
Если вы хотите только определить, встречается ли конкретная иголка в стоге сена, используйте
strpos()
вместо этого более быструю и менее интенсивную функцию памяти .
if(strpos($haystack,$needle) !== false) { // do something }
, никогда if(strpos($haystack,$needle)) { // do bad things }
. strpos
вернет 0, если $needle
находится в самом начале $haystack
, и 0 считается равным false. (0 == false)
оценивается как истина. (0 === false)
оценивается как ложь.
Вот еще несколько ответов (+ тесты). Я получил почти такой же вопрос (я не понял вашего, когда спрашивал).
В то же время я также сделал свой собственный тест бенчмарк, который я выбежала 1000000 раз для каждого соответствующих функций ( strstr()
, strpos()
, stristr()
и stripos()
).
Вот код:
<?php
function getmicrotime() {
list($usec, $sec) = explode(" ", microtime());
return ((float) $usec + (float) $sec);
}
$mystring = 'blahblahblah';
$findme = 'bla';
echo 'strstr & strpos TEST:<pre>';
$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) strstr($mystring, $findme);
$time_needed_strstr = getmicrotime() - $time_start;
echo 'strstr(): ',
round( $time_needed_strstr , 8 ). PHP_EOL;
$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) stristr($mystring, $findme);
$time_needed_stristr = getmicrotime() - $time_start;
echo 'stristr(): ',
round( $time_needed_stristr , 8 ) . PHP_EOL;
$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) strpos($mystring, $findme) !== false;
$time_needed_strpos = getmicrotime() - $time_start;
echo 'strpos() !== false: ',
round( $time_needed_strpos , 8 ) . PHP_EOL;
$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) stripos($mystring, $findme) !== false;
$time_needed_stripos = getmicrotime() - $time_start;
echo 'stripos() !== false: ',
round( $time_needed_stripos , 8 ) . PHP_EOL;
echo PHP_EOL;
echo 'time_needed_stristr - time_needed_strstr: ',
round( $time_needed_stristr - $time_needed_strstr , 8) . PHP_EOL;
echo 'time_needed_stripos - time_needed_strpos: ',
round( $time_needed_stripos - $time_needed_strpos , 8) . PHP_EOL;
echo PHP_EOL;
echo 'time_needed_strstr - time_needed_strpos: ',
round( $time_needed_strstr - $time_needed_strpos , 8) . PHP_EOL;
echo 'time_needed_stristr - time_needed_stripos: ',
round( $time_needed_stristr - $time_needed_stripos , 8) . PHP_EOL;
echo '</pre>';
?>
И вот первый результат, который показывает, что strpos()
победитель :
strstr & strpos TEST:
strstr(): 2.39144707
stristr(): 3.65685797
strpos() !== false: 2.39055395
stripos() !== false: 3.54681897
time_needed_stristr - time_needed_strstr: 1.2654109
time_needed_stripos - time_needed_strpos: 1.15626502
time_needed_strstr - time_needed_strpos: 0.00089312
time_needed_stristr - time_needed_stripos: 0.110039
Следующий результат аналогичен первому ( strpos()
снова победитель):
strstr & strpos TEST:
strstr(): 2.39969015
stristr(): 3.60772395
strpos() !== false: 2.38610101
stripos() !== false: 3.34951186
time_needed_stristr - time_needed_strstr: 1.2080338
time_needed_stripos - time_needed_strpos: 0.96341085
time_needed_strstr - time_needed_strpos: 0.01358914
time_needed_stristr - time_needed_stripos: 0.25821209
Ниже еще один, более интересный, потому что в этом случае strstr()
победитель:
strstr & strpos TEST:
strstr(): 2.35499191
stristr(): 3.60589004
strpos() !== false: 2.37646604
stripos() !== false: 3.51773095
time_needed_stristr - time_needed_strstr: 1.25089812
time_needed_stripos - time_needed_strpos: 1.14126492
time_needed_strstr - time_needed_strpos: -0.02147412
time_needed_stristr - time_needed_stripos: 0.08815908
Это означает, что это действительно может зависеть от «условий окружающей среды» , на которые иногда трудно повлиять, и может изменить результат подобных «задач микрооптимизации», если вы просто проверяете, существует ли строка в другой строке или нет.
НО я думаю, что в большинстве случаев strpos()
это победитель по сравнению с strstr()
.
Надеюсь, этот тест был кому-то полезен.
Многие разработчики используют его strpos
для микрооптимизации .
Использование strstr
также работает только в том случае, если результирующая строка не может быть интерпретирована как ложь в логическом контексте.
strpos()
. Если мне нужна подстрока после этой позиции, я вызываю strstr()
.
strstr
делает больше, чем требуется, поэтому он медленнее.
strpos () определяет, где в стоге сена лежит конкретная иголка. stristr () проверяет, находится ли иголка где-нибудь в стоге сена
поэтому strpos () работает быстрее и потребляет меньше памяти
причина для strstr (): если ваша стрелка находится в начале строки, strpos возвращает 0 (поэтому необходимо проверить это с помощью === false)
strstr()
возвращает все до или после иглы, поэтому сначала нужно выполнить эквивалент, strpos()
а затем создать эту подстроку . Вот где падает производительность.
Я предпочитаю strstr()
удобочитаемость и простоту кодирования .. strpos() !==false
немного сбивает с толку ..
strstr
слишком похож наstrtr
strstr
тоже требует строгого сравнения Пример:('123450', '0')