Вопрос по arrays, php – Почему in_array () ошибочно возвращает true с этими (большими числовыми) строками?
Я не понимаю, что не так с этим кодом. Он возвращает "найдено", чего не должно быть.
<code>$lead = "418176000000069007"; $diff = array("418176000000069003","418176000000057001"); if (in_array($lead,$diff)) echo "Found"; else echo "Not found"; </code>
Note: это поведение было изменено в PHP 5.4.
По умолчанию,in_array
использует свободное сравнение (==
), что означает, что числовые строки преобразуются в числа и сравниваются как числа. До PHP 5.4, если у вас не было достаточной точности в типе с плавающей точкой вашей платформы, разница была потеряна, и вы получили неправильный ответ.
Решение состоит в том, чтобы включитьstrict
сравнение (===
), передав дополнительнуюBoolean
параметр дляin_array
:
$lead = "418176000000069007";
$diff = array("418176000000069003", "418176000000057001");
if ( in_array($lead, $diff, true) )
echo "Found";
else
echo "Not found";
Затем строки сравниваются как строки без числового приведения. Однако это означает, что вы теряете эквивалентность строк по умолчанию, например & quot; 01234 & quot; и "1234".
Это поведениебыло сообщено как ошибка и исправлено в PHP 5.4. Числовые строки по-прежнему преобразуются в числа по сравнению с==
, но только если значение строки соответствует числовому типу платформы.
php -r 'echo("4181760000000000069003" == "4181760000000000057001"),"\n";'
возвращает 1.
418176000000069007
изменен на 2147483647 (целочисленный предел PHP). Вот почему вы получаетеFound
.
пытаться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.
$strict
вtrue
: in_array($lead, $diff, true)
int
совсем?
и вы действительно хотите сравнить / найти в массиве, то есть хитрость
$lead = "a418176000000069007";
$diff = array("a418176000000069003","a418176000000057001");
if (in_array($lead,$diff))
echo "Found";
else
echo "Not found";
то есть каким-то образом вы должны добавлять символ perticular к каждому числу. Они будут вести себя как строки в сравнении и, следовательно, будут давать правильный результат.
in_array()
Функция также проверит типы иголки в стоге сена, а также потому, что предел превышает максимальное целочисленное значение.
Таким образом, если PHP встречает число за пределами целочисленного типа, оно будет интерпретироваться как число с плавающей точкой. Кроме того, операция, результатом которой является число, выходящее за пределы целочисленного типа, вместо этого вернет число с плавающей запятой. Проверьте руководства по PHP.
if (in_array($lead,$diff,true))
Руководство по 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'. Otherwise, it will be evaluated as an integer.
Как уже упоминалось, вы должны использовать строгийin_array:
bool in_array ( mixed $needle , array $haystack [, bool $strict =
FALSE ] ) Searches haystack for needle using loose comparison unless
strict is set.
Некоторые упоминалиPHP_INT_MAX
, Это было бы2147483647
в моей системе. Я не совсем уверен, что это проблема, посколькуручные состояния:
If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.
Ноточность с плавающей точкой должно быть достаточно высоким ...
Что бы ни было «реальным» источник этой проблемы, просто используйте строгийin_array
чтобы исправить эту проблему.
PHP
,this was a bug and is rectified and solved in newer versions of PHP
.
Значения превышаютPHP_INT_MAX
.
Пробоватьecho
/print_r
$lead
а также$diff
без использования кавычек. Это приведет
$lead ---> 418176000000070000
$diff ---> Array ( [0] => 418176000000070000 [1] => 418176000000060000 )
так что в этом случаеin_array
результат верный!
так что пользуйтесьstrict
сравнение вin_array()
установив третий аргумент вin_array()
какtrue
if(in_array($lead,$diff,true)) //use type too
echo "Found";
else
echo "Not found";
?>
Попробуй это. Это будет работать.
in_array
должен быть строгим.
$diff = array("418176000000069003","418176000000057001");
if(in_array($lead,$diff,true))
echo "Found";
else
echo "Not found";
Эта проблема связана сyour numbers are exceeded from the defined integer limit
Примечание: максимальное значение зависит от системы. 32-битные системы имеют максимальный целочисленный диапазон со знаком-2147483648
в2147483647
, Так, например, в такой системе,intval('1000000000000')
вернусь2147483647
, Максимальное целочисленное значение со знаком для 64-битных систем9223372036854775807
.