Почему in_array () ошибочно возвращает true с этими (большими числовыми) строками?

Я не понимаю, что не так с этим кодом. Он возвращает «Найден», чего не следует.

$lead = "418176000000069007"; $diff = array("418176000000069003","418176000000057001"); if (in_array($lead,$diff)) echo "Found"; else echo "Not found"; 

Это из-за ограничений хранения номера в PHP , это была ошибка и исправлена ​​и решена в более новых версиях 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"; ?> 

Попробуй это. Это будет работать.

Примечание: это поведение было изменено в 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"; 

Затем строки сравниваются как строки без численного принуждения. Однако это означает, что вы теряете стандартную эквивалентность строк, таких как «01234» и «1234».

Это поведение было зарегистрировано как ошибка и исправлено в PHP 5.4. Числовые строки по-прежнему преобразуются в числа по сравнению с символом == , но только если значение строки соответствует числовому типу платформы.

Это из-за одного дефекта в PHP. 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. 

Значения превышают PHP_INT_MAX . Попробуйте сделать, if(in_array($lead,$diff,true)) .

in_array следует ограничивать.

 $lead = "418176000000069007"; $diff = array("418176000000069003","418176000000057001"); if(in_array($lead,$diff,true)) echo "Found"; else echo "Not found"; 

Эта проблема возникает из-за превышения ваших чисел из заданного целочисленного предела

Примечание: максимальное значение зависит от системы. 32-разрядные системы имеют максимальный знаковый целочисленный диапазон от -2147483648 до 2147483647 . Так, например, в такой системе intval('1000000000000') вернет 2147483647 . Максимальное знаковое целочисленное значение для 64-битных систем – 9223372036854775807 .

Попробуйте использовать скобки и используйте строгий режим:

 $lead = "418176000000069007"; $diff = array("418176000000069003","418176000000057001"); if(in_array($lead, $diff, true)) { echo "Found"; } else { echo "Not found"; } 

Если для третьего параметра strict установлено значение TRUE, функция in_array() также проверит типы иглы в стоге сена и потому, что предел превышает максимальное целочисленное значение.

Поэтому, если PHP встречает число за пределами целочисленного типа, оно будет интерпретироваться как float. Кроме того, операция, которая приводит к числу за пределами целочисленного типа, вместо этого возвращает float. Проверьте руководства PHP.

 if (in_array($lead,$diff,true)) 

Из руководства PHP: преобразование строк в номера :

Когда строка оценивается в числовом контексте, результирующее значение и тип определяются следующим образом.

Строка будет оцениваться как float, если она содержит какие-либо символы '.', 'E' или 'E'. В противном случае он будет оцениваться как целое число.

Как уже упоминалось, вы должны использовать строго для in_array :

bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE]) Искает стог сена для иглы, используя свободное сравнение, если не установлено строгое значение.

Некоторые упомянули PHP_INT_MAX . Это будет 2147483647 в моей системе. Я не совсем уверен, что это проблема, поскольку в руководстве указано :

Если PHP встречает число за пределами целочисленного типа, оно будет интерпретироваться как float. Кроме того, операция, которая приводит к числу за пределами целочисленного типа, вместо этого возвращает float.

Но точность с плавающей запятой должна быть достаточно высокой …

Каким бы ни был «реальный» источник этой проблемы, просто используйте strict для in_array чтобы исправить эту проблему.

Если это ваша проблема, и вы действительно хотите сравнить / найти в массиве, тогда есть трюк

 $lead = "a418176000000069007"; $diff = array("a418176000000069003","a418176000000057001"); if (in_array($lead,$diff)) echo "Found"; else echo "Not found"; 

т. е. каким-то образом вы должны придать каждому члену характерный характер. Они будут вести себя как строки в сравнении и, следовательно, давать правильный результат.