[英]Checking for existence in a string with strpos
I've only ever seen developers use strict comparisons when they use strpos
to check for the existence of a substring: 我只见过开发人员在使用
strpos
检查子字符串是否存在时使用严格的比较:
if (strpos($haystack,$needle) !== false) {
}
It occurred to me today that one could use is_numeric
ins 今天我想到可以使用
is_numeric
ins
if (is_numeric(strpos($haystack,$needle))) {
}
Is there a reason one would use one over the other (specifically in this use case)? 是否有一个理由会使用另一个理由(特别是在此用例中)?
If you think about it, the purpose of strpos
is to return the position of the substring. 如果您考虑一下,
strpos
的目的是返回子字符串的位置 。 Only if it doesn't exist, will it return false. 仅当它不存在时,它才会返回false。 The position is a number .
该职位是一个数字 。 Thus,
is_numeric
is pretty qualified to be considered semantically. 因此,
is_numeric
非常适合在语义上考虑。
I've created a benchmark. 我已经创建了一个基准。 Case
check by compare with false value
always faster than check by is_numeric
. check by compare with false value
大小写check by compare with false value
总是比check by is_numeric
check by compare with false value
大小写check by compare with false value
更快。
// 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
I found this question searching for almost the same question, except my thought was to use is_int( )
not is_numeric( )
. 我发现这个问题正在搜索几乎相同的问题,除了我的想法是使用
is_int( )
而不是is_numeric( )
。 I couldn't really understand the benchmark that was posted so I made my own. 我不太了解所发布的基准测试,因此我自己制定了基准测试。 In short,
is_numeric( )
is a hair slower than !== false
, and is_int( )
is a hair faster. 简而言之,
is_numeric( )
的头发速度比!== false
慢,而is_int( )
的头发速度更快。 Personally, I find it more readable than !== false
not less, so I'll probably switch to it. 就个人而言,我发现它比
!== false
更易读,所以我可能会改用它。
This was done under php v7.1.23 这是在php v7.1.23下完成的
Results: 结果:
0.7900s for '!== false' with hits
4.5137s for '!== false' with misses
0.9297s for 'is_numeric' with hits
4.7509s for 'is_numeric' with misses
0.6391s for 'is_int' with hits
4.4862s for 'is_int' with misses
From the code: 从代码:
$n_times = 10000000;
$haystack_hit = " Certificate Name: example.com";
$heystack_miss = "Found the following certs:";
$needle = "Certificate Name:";
$start = microtime(true);
for($i = 0; $i < $n_times; $i++)
{
if (strpos($haystack_hit,$needle) !== false)
{ }
}
$end = microtime(true) - $start;
echo "\n" . round($end,4) . "s for '!== false' with hits\n";
$start = microtime(true);
for($i = 0; $i < $n_times; $i++)
{
if (strpos($haystack_miss,$needle) !== false)
{ }
}
$end = microtime(true) - $start;
echo round($end,4) . "s for '!== false' with misses\n\n";
// -----
$start = microtime(true);
for($i = 0; $i < $n_times; $i++)
{
if ( is_numeric(strpos($haystack_hit,$needle)) )
{ }
}
$end = microtime(true) - $start;
echo round($end,4) . "s for 'is_numeric' with hits\n";
$start = microtime(true);
for($i = 0; $i < $n_times; $i++)
{
if ( is_numeric(strpos($haystack_miss,$needle)) )
{ }
}
$end = microtime(true) - $start;
echo round($end,4) . "s for 'is_numeric' with misses\n\n";
// -----
$start = microtime(true);
for($i = 0; $i < $n_times; $i++)
{
if ( is_int(strpos($haystack_hit,$needle)) )
{ }
}
$end = microtime(true) - $start;
echo round($end,4) . "s for 'is_int' with hits\n";
$start = microtime(true);
for($i = 0; $i < $n_times; $i++)
{
if ( is_int(strpos($haystack_miss,$needle)) )
{ }
}
$end = microtime(true) - $start;
echo round($end,4) . "s for 'is_int' with misses\n";
Since strpos
returns either integer or boolean false it's okay to use is_numeric
. 由于
strpos
返回整数或布尔值false,因此可以使用is_numeric
。
The question is: 问题是:
What is more idiomatic and autodocumented/self-descriptive , using is_numeric
or comparing return value to boolean? 使用
is_numeric
或将返回值与布尔值进行比较,还有什么更惯用和自动记录/自我描述 ? IMO, comparing to boolean false is much more intuitive: IMO,与布尔假相比,更加直观:
$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";
Also, strpos(...) !== false
is overused because it's what PHP documentation suggests. 另外,
strpos(...) !== false
被过度使用,因为这是PHP文档所建议的。 Thus it has become conventional. 因此,这已成为常规。
There is no reason why would anybody use is_numeric, but it will work, only slower. 没有任何人会使用is_numeric的理由,但是它将起作用,只是速度较慢。
About strpos vs preg_match: preg_match() vs strpos() for match finding? 关于strpos vs preg_match: preg_match()vs strpos()用于匹配查找? and which is the fast process strpos()/stripos() or preg_match() in php
这是PHP中的快速过程strpos()/ stripos()或preg_match()
You are right, is_numeric
works with strpos
. 没错,
is_numeric
可与strpos
。 But this can make the code tricky, hence lowering code readability. 但这会使代码变得棘手,从而降低了代码的可读性。
Have in mind that although this may seems obvious to you, you are making another programmer that reads your code think in a lot of things: 请记住,尽管这对您来说似乎很明显,但是您正在使另一个读取您的代码的程序员在很多方面都进行了思考:
And PHP can be quite a tricky language by itself, take a look at this examples: 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>";
}
Imho, the best option is using ===false
and ==!false
comparisons, like explained in the php documentation for strpos : 恕我直言,最好的选择是使用
===false
和==!false
比较,就像在strpos的php文档中解释的那样:
Warning This function may return Boolean FALSE , but may also return a non-Boolean value which evaluates to FALSE.
警告此函数可能返回布尔值FALSE ,但也可能返回非布尔值,其值为FALSE。 Please read the section on Booleans for more information.
请阅读布尔值部分以获取更多信息。 Use the === operator for testing the return value of this function.
使用===运算符测试此函数的返回值。
PD: For a better definition of "truthy" take a look at this post . PD:有关“真实”的更好定义,请看一下这篇文章 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.