Проверка существования в строке с помощью strpos
Я только когда-либо видел, чтобы разработчики использовали строгие сравнения, когда они используют strpos
для проверки существования подстроки:
if (strpos($haystack,$needle) !== false) {
}
Сегодня мне пришло в голову, что один может использовать is_numeric
ins
if (is_numeric(strpos($haystack,$needle))) {
}
Есть ли причина, по которой один будет использовать один над другим (особенно в этом случае использования)?
Если подумать, то цель strpos
состоит в том, чтобы вернуть позицию подстроки. Только если он не существует, он возвратит ложь. Позиция число . Таким образом, is_numeric
достаточно квалифицирован, чтобы быть рассмотренным семантически.
4 ответа:
Я создал эталон. Случай
check by compare with false value
всегда быстрее, чемcheck by is_numeric
.// Init a big string array for($i = 0; $i < 10000; $i++){ $str[] = 'a'.rand().'b'.rand(); } // Case comparing with false value $time1 = microtime(true); foreach($str as $st){ $res[] = strpos($st,rand(0, count(array('b', 'c')) - 1 )) !== false; } $time2 = microtime(true); echo $time2-$time1.'<br/>'; // Case 'is_numeric' $time3 = microtime(true); foreach($str as $st){ $res[] = is_numeric(strpos($st,rand(0, count(array('b', 'c')) - 1 ))); } $time4 = microtime(true); echo $time4-$time3; //Time 1: //0.018877029418945 //0.020556926727295 //Time 2: //0.016352891921997 //0.016934871673584 //Time 3: //0.0121009349823 //0.01330304145813 //Time 4: //0.017507076263428 //0.01904296875
Поскольку
strpos
возвращает либо целое число, либо логическое значение false, можно использоватьis_numeric
.
Вопрос в следующем:
Что является более идиоматическим и автодокументированным / самоописательным , использующимis_numeric
или сравнивающим возвращаемое значение с булевым? IMO, по сравнению с boolean false, гораздо более интуитивно понятен:$string = 'new object'; $found = strpos($string,'new'); echo (is_numeric($found)) ? 'found' : 'not found'; echo "\n"; # much better echo ($found !== false) ? 'found' : 'not found'; echo "\n";
Также,
strpos(...) !== false
используется слишком часто, потому что это то, что предполагает документация PHP. Таким образом, оно стало общепринятым.
- Использование strpos в этом контексте является для is большей скоростью по сравнению с preg_match, использование is_numeric поверх него отрицает это преимущество скорости, добавляя больше накладных расходов.
- Использование другой функции только для отделения false от остальных не имеет смысла, лучше просто использовать != = false
Нет никаких причин, почему кто-то будет использовать is_numeric, но он будет работать, только медленнее.
О strpos vs preg_match: preg_match () vs strpos () для поиска совпадений? и который является быстрый процесс strpos()/stripos () или preg_match () в php
Вы правы,
Имейте в виду, что, хотя это может показаться вам очевидным, вы заставляете другого программиста, который читает ваш код, думать о многих вещах:is_numeric
работает сstrpos
. Но это может сделать код сложным, следовательно, снижая читаемость кода.Содержит ли стог сена иголку? Каково положение иглы в стоге сена?
- Какой тип значения возвращает strpos?
- является ли возвращаемое значение strpos числом в этом случае?
И PHP может быть довольно сложным языком сам по себе, взгляните на эти примеры:
if (strpos("needle in a haystack","needle")!==false) { echo "Needle found!<br>"; } else { echo "nothing found<br>"; } if (is_numeric(strpos("needle in a haystack","needle"))) { echo "Needle found!<br>"; } else { echo "nothing found<br>"; } if (is_int(strpos("needle in a haystack","needle"))) { echo "Needle found!<br>"; } else { echo "nothing found<br>"; } // This doesn't work since 0 == false is true if (strpos("needle in a haystack","needle")!=false) { echo "Needle found!<br>"; } else { echo "nothing found<br>"; } // But this works since "haystack" position is not 0 if (strpos("needle in a haystack","haystack")!=false) { echo "Haystack found!<br>"; } else { echo "nothing found<br>"; } // This doesn't work also because "needle" is at 0, and 0 is not a truthy value if (strpos("needle in a haystack","needle")) { echo "Needle found!<br>"; } else { echo "nothing found<br>"; } // But this works again since "haystack" position is not 0, and any int that's not 0 is truthy if (strpos("needle in a haystack","haystack")) { echo "Haystack found!<br>"; } else { echo "nothing found<br>"; }
Имхо, лучшим вариантом является использование сравнений
===false
и==!false
, как описано в документации php для strpos :Предупреждение Эта функция может возвращать логическое ложные, но может также возвращает не булево значение, которое принимает значение false. Пожалуйста, прочитайте раздел о логических значениях для получения дополнительной информации. Используйте оператор === для проверки возвращаемого значения этой функции.
PD: для лучшего определения "правдивости" взгляните на этот пост.