Подтвердить что ты не робот

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

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

$lead = "418176000000069007";
$diff = array("418176000000069003","418176000000057001");

if (in_array($lead,$diff))
    echo "Found";
else
    echo "Not found";
4b9b3361

Ответ 1

Именно из-за ограничений хранения номера в 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";
?>

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

Ответ 2

Примечание. это поведение было изменено в 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. Числовые строки по-прежнему преобразуются в числа по сравнению с ==, но только в том случае, если значение строки соответствует числовому типу платформы.

Ответ 3

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

Ответ 4

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

Ответ 5

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.

Ответ 6

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

$lead = "418176000000069007";
$diff = array("418176000000069003","418176000000057001");

if(in_array($lead, $diff, true)) {
    echo "Found";
} else {
    echo "Not found";
}

Ответ 7

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

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

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

Ответ 8

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

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

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

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

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

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

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

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

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

Ответ 9

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

$lead = "a418176000000069007";
$diff = array("a418176000000069003","a418176000000057001");

if (in_array($lead,$diff))
    echo "Found";
else
    echo "Not found";

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