-3

PHP 7

in_array('one', [0 => 0]) //true
in_array('one', [0]) //true
in_array('one', array_keys([0 => 0])); //true

Expected result is FALSE, because obviously there are no string values in given array, also there are no 'true' values (string can be evaluated to true and match)

If we assume any type comparsion 0 integer is always compared to false in PHP, and String compared to true, so why this works anyway?

I know, strict mode exists and works fine, but anyway absolute annoying why this happend. Any explanation?

YanAlex
  • 99
  • 1
  • 10
  • What's the problem? –  Sep 22 '20 at 09:10
  • It should be FASLE, there are no values in array matching string 'one' – YanAlex Sep 22 '20 at 09:11
  • Please add that to your question. We need to know what's going on to help you! –  Sep 22 '20 at 09:13
  • I did this,please check – YanAlex Sep 22 '20 at 09:17
  • read [the manual](https://www.php.net/manual/en/types.comparisons.php) on type comparisons, and as you say, always use strict so you won't shoot yourself in the foot... - an [answer](https://www.php.net/manual/en/types.comparisons.php#49327) from 15 years ago explains it in short. – jibsteroos Sep 22 '20 at 09:23
  • Okay 0 integer is always compared to false in PHP, and String compared to true, so why this works ? – YanAlex Sep 22 '20 at 09:28
  • have a look at [this](https://3v4l.org/jdZm0) it also shows there's a change for PHP8.0.0. beta1-beta3 (string "one" DOES NOT equal 0 anymore) – jibsteroos Sep 22 '20 at 09:51
  • But Strings ("one") always been casted to (1 or true) that means 0 != "one" but it gives true if we use in_array – YanAlex Sep 22 '20 at 09:59
  • 1
    @user1713785 no, `'one'` is `true` in a **boolean** context. In an integer context (e.g. comparing it to `0`), the string is converted to an integer; and since it doesn't begin with any digits, it evaluates to `0`. See for example https://3v4l.org/XpEUp, `'1one' == 1` but `'one' == 0` – Nick Sep 22 '20 at 11:35
  • @jibsteroos interesting, I had not noticed that in the updates. – Nick Sep 22 '20 at 11:37
  • @Nick, yeah, same here, it just struck me when I ran it on 3v4l – jibsteroos Sep 22 '20 at 11:40
  • @user1713785 absolutely correct. My opinion was it should be casted to boolean. Thanks a lot! – YanAlex Sep 22 '20 at 15:00

3 Answers3

1

The answer to your question is here:

Comparing String to Integer gives strange results

Same situation when "one" == 0 as in your examples.

TL:DR - on string-to-integer comparison the string will be converted to integer, not the integer to string, so "one" will be converted to 0

Anton
  • 2,669
  • 1
  • 7
  • 15
  • Thanks, I was thinking it should be casted to boolean. Now I see the integer is more close in this case. – YanAlex Sep 22 '20 at 15:02
0

in_array works when u use it like this

in_array('one', [0,1])
Hammad Ahmed khan
  • 1,618
  • 7
  • 19
0

in_array function expect array as indexed array i.e [0,1,"two"] not associative array (Key value pair). You can use array_values to ignore the key of specific, it returns only values.

in_array('one', array_values([0 => 0])) // true //tested
Haris Khurshid
  • 294
  • 2
  • 7
  • I faced this problem starting from array_keys, in your example also result is TRUE when it should be FALSE. Look at my fist post, edited – YanAlex Sep 22 '20 at 09:30
  • @user1713785 `in_array('one', array_values([0 => 0]),TRUE)` pass 3rd parameter `TRUE` for **type specefic**. Hope it helps – Haris Khurshid Sep 22 '20 at 09:36
  • Thanks, i know about strict mode, thi is intresting behavior when in default mode – YanAlex Sep 22 '20 at 09:58