[英]Why does in_array() wrongly return true with these (large numeric) strings?
I am not getting what is wrong with this code.我不明白这段代码有什么问题。 It's returning "Found", which it should not.它正在返回“找到”,它不应该。
$lead = "418176000000069007";
$diff = array("418176000000069003","418176000000057001");
if (in_array($lead,$diff))
echo "Found";
else
echo "Not found";
Note: this behavior was changed in PHP 5.4.注意:此行为已在 PHP 5.4 中更改。
By default, in_array
uses loose comparison ( ==
), which means numeric strings are converted to numbers and compared as numbers.默认情况下, in_array
使用松散比较 ( ==
),这意味着数字字符串被转换为数字并作为数字进行比较。 Before PHP 5.4, if you didn't have enough precision in your platform's floating-point type, the difference was lost and you got the wrong answer.在 PHP 5.4 之前,如果您在平台的浮点类型中没有足够的精度,差异就会丢失,并且您会得到错误的答案。
A solution is to turn on strict
comparison ( ===
) by passing an extra Boolean
parameter to in_array
:一个解决方案是通过向in_array
传递一个额外的Boolean
参数来打开strict
比较( ===
):
$lead = "418176000000069007";
$diff = array("418176000000069003", "418176000000057001");
if ( in_array($lead, $diff, true) )
echo "Found";
else
echo "Not found";
Then the strings are compared as strings with no numeric coercion.然后将字符串作为没有数字强制的字符串进行比较。 However, this means you do lose the default equivalence of strings like "01234" and "1234".但是,这意味着您确实会丢失“01234”和“1234”等字符串的默认等效项。
This behavior was reported as a bug and fixed in PHP 5.4.此行为被报告为错误并在 PHP 5.4 中修复。 Numeric strings are still converted to numbers when compared with ==
, but only if the value of the string fits in the platform's numeric type.与==
相比时,数字字符串仍会转换为数字,但==
是字符串的值适合平台的数字类型。
Note: This was a bug in PHP old versions and is corrected in PHP 5.4
and newer versions.注意:这是 PHP 旧版本中的一个错误,在PHP 5.4
和更新版本中已更正。
It is because of the limitations of the number storage in PHP
这是因为PHP
数字存储的限制
The real problem here is because of the PHP_INT_MAX
- the value exceeded in our case.这里真正的问题是因为PHP_INT_MAX
- 在我们的例子中超出了这个值。
Try to echo
/ print_r
$lead
and $diff
without using the quotes.尝试在不使用引号的情况下echo
/ print_r
$lead
和$diff
。 It will result它会导致
$lead ---> 418176000000070000
$diff ---> Array ( [0] => 418176000000070000 [1] => 418176000000060000 )
so, in this case, the in_array
result is true!所以,在这种情况下, in_array
结果为真!
so use strict
comparison in in_array()
by setting third argument in in_array()
as true
因此,通过将in_array()
的第三个参数设置为true
在in_array()
使用strict
比较
if(in_array($lead,$diff,true)) //use type too
echo "Found";
else
echo "Not found";
?>
Try this.试试这个。 It will work.它会起作用。
It's because of one defect in PHP.这是因为 PHP 中的一个缺陷。 418176000000069007
is modified to 2147483647 (integer limit of PHP). 418176000000069007
修改为2147483647(PHP整数限制)。 That is why you are getting Found
.这就是你得到Found
。
try in_array($lead, $diff, true)
尝试in_array($lead, $diff, true)
If the third parameter strict is set to TRUE then the in_array()
function will also check the types of the needle in the haystack.
The values exceed PHP_INT_MAX
.值超过PHP_INT_MAX
。 Try doing if(in_array($lead,$diff,true))
instead.尝试做if(in_array($lead,$diff,true))
代替。
in_array
should be stricted. in_array
应该是严格的。
$lead = "418176000000069007";
$diff = array("418176000000069003","418176000000057001");
if(in_array($lead,$diff,true))
echo "Found";
else
echo "Not found";
This problem is due to your numbers are exceeded from the defined integer limit此问题是由于您的数字超出了定义的整数限制
Note: the maximum value depends on the system.注意:最大值取决于系统。 32 bit systems have a maximum signed integer range of -2147483648
to 2147483647
. 32 位系统的最大有符号整数范围为-2147483648
到2147483647
。 So for example on such a system, intval('1000000000000')
will return 2147483647
.因此,例如在这样的系统上, intval('1000000000000')
将返回2147483647
。 The maximum signed integer value for 64 bit systems is 9223372036854775807
. 64 位系统的最大有符号整数值为9223372036854775807
。
Try using brackets and use strict mode:尝试使用括号并使用严格模式:
$lead = "418176000000069007";
$diff = array("418176000000069003","418176000000057001");
if(in_array($lead, $diff, true)) {
echo "Found";
} else {
echo "Not found";
}
If the third parameter strict is set to TRUE then the in_array()
function will also check the types of the needle in the haystack, and because the limit is beyond the maximum integer value.如果第三个参数 strict 设置为 TRUE,则in_array()
函数还将检查大海捞针的类型,并且因为限制超出了最大整数值。
So if PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead.因此,如果 PHP 遇到超出整数类型范围的数字,则会将其解释为浮点数。 Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.此外,导致数字超出整数类型范围的操作将改为返回浮点数。 Check the PHP manuals.检查 PHP 手册。
if (in_array($lead,$diff,true))
From PHP Manual: String conversion to numbers :从PHP 手册:字符串转换为数字:
When a string is evaluated in a numeric context, the resulting value and type are determined as follows.当在数字上下文中计算字符串时,结果值和类型按如下方式确定。
The string will be evaluated as a float if it contains any of the characters '.', 'e', or 'E'.如果字符串包含任何字符“.”、“e”或“E”,则该字符串将被评估为浮点数。 Otherwise, it will be evaluated as an integer.否则,它将被评估为整数。
As some others mentioned, you should use strict for in_array :正如其他一些人提到的,您应该对in_array使用严格:
bool in_array ( mixed $needle , array $haystack [, bool $strict =
FALSE ] ) Searches haystack for needle using loose comparison unless strict is set.bool in_array ( mixed $needle , array $haystack [, bool $strict =
FALSE ] ) 除非设置了strict,否则使用松散比较在haystack 中搜索needle。
Some mentioned PHP_INT_MAX
.有些人提到了PHP_INT_MAX
。 This would be 2147483647
on my system.在我的系统上这将是2147483647
。 I'm not quite sure if this is the problem as the manual states :我不太确定这是否是手册所述的问题:
If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead.如果 PHP 遇到超出整数类型范围的数字,则会将其解释为浮点数。 Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.此外,导致数字超出整数类型范围的操作将改为返回浮点数。
But floating point precision should be high enough...但是浮点精度应该足够高......
Whatever might be the "real" source of this problem, simply use strict for in_array
to fix this problem.无论此问题的“真正”根源是什么,只需对in_array
使用 strict 即可解决此问题。
If that is your problem and you really want to compare/find in array then there is a trick如果这是您的问题并且您真的想在数组中进行比较/查找,那么有一个技巧
$lead = "a418176000000069007";
$diff = array("a418176000000069003","a418176000000057001");
if (in_array($lead,$diff))
echo "Found";
else
echo "Not found";
ie somehow you have to prepend a perticular character to every number.即不知何故,您必须为每个数字添加一个特定的字符。 They will behave as strings in comparison and hence give correct result.相比之下,它们将表现为字符串,因此会给出正确的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.