4

I have an array of lower case hex strings. For some reason, in_array is finding matches where none exist:

$x = '000e286592';
$y = '0e06452425';
$testarray = [];
$testarray[] = $x;
if (in_array($y, $testarray)) {
    echo "Array element ".$y." already exists in text array ";
}
print_r($testarray);exit();

The in_array comes back as true, as if '0e06452425' is already in the array. Which it is not. Why does this happen and how do I stop it from happening?

  • 1
    `print($x + $y)` resolves as `0`. Likely because of the same reason: loose comparisons, implicit casting., and type juggling. It's interpreting the string `0e06452425` as "0 times 10 raised to 6452425" which is `0`. So `0` is in fact in the array that also contains `0` and you get a `true`. It's silly, but php is often silly. – JNevill Oct 18 '22 at 17:52
  • Issue happens only if the string starts with "0". Looks like some bug and the in_array may be treating the string as octal integer – Pran Joseph Oct 18 '22 at 17:58

2 Answers2

2

Odd. This has something to do with the way that PHP compares the values in "non-strict" mode; passing the third argument (strict) as true no longer results in a false positive:

if (in_array($y, $testarray, true)) {
    echo "Array element ".$y." already exists in text array ";
}

I'm still trying to figure out why, technically speaking, this doesn't work without strict checking enabled.

esqew
  • 42,425
  • 27
  • 92
  • 132
  • PHP defaults to truthy statements and loose comparisons by default .. Setting to `true` forces strict comparison. – Zak Oct 18 '22 at 17:50
  • 1
    If a number begins with 0 it will be handled as octal not decimal. That's why you need strict comparision to take it as strings. https://www.php.net/manual/en/language.types.integer.php – Markus Zeller Oct 18 '22 at 17:54
  • 1
    @MarkusZeller not with string casting, only with numeric literals. `(int)'012'` is `12`, `012` is `10`. – Sammitch Oct 18 '22 at 19:25
  • @Sammitch When you do a typeless comparision PHP internally tries a cast match before comparing. So you're correct, it is not a casting problem. So I think JNevill`s comment on the question takes part here. – Markus Zeller Oct 18 '22 at 19:36
1

You can pass a boolean as third parameter to in_array() to enable PHP strict comparison instead of the default loose comparison.

Try this code

$x = '000e286592';
$y = '0e06452425';
$testarray = [];
$testarray[] = $x;
if (in_array($y, $testarray, true)) {
    echo "Array element ".$y." already exists in text array ";
}
print_r($testarray);exit();
Mehrdad Moradi
  • 521
  • 1
  • 6
  • 21