in_array() vs. array_key_exists()

Hi, everyone.

Can someone explain why PHP behaves the way it does, in this example?

I have this little demo script:




<?php

$arr = array('apple', 'orange', 'banana');

var_dump(in_array('no i dont have this here!!!', array_keys($arr))); // return true

var_dump(array_key_exists('no i dont have this here!!!', $arr)); // returns false

?>



Now my question is: Why does in_array() returns true in this case? I thought that these constructs would return the same (false).

Thanks for your help.

Set the last parameter of in_array (strict) to TRUE and the result is correct ;)

Yes, you are right, but I still don’t understand why. This parameter makes sense if I want to test for 1 but not for “1”. In my case the string “no i dont…” obviously doesn’t exist in any type in this array.

btw. This is also mentioned on the manual page: http://at.php.net/manual/de/function.in-array.php#106319

However there isn’t an explanation either.

(Sorry my English is not the best)

I think you dont want to use array_keys.

You want array_values right?


var_dump(in_array('no i dont have this here!!!', array_values($arr))); // return false

If you NOT enable strict-mode then PHP converts your string to int(0) and the first key of your array is int(0)

If strict-mode is enabled, PHP checks the type also.


<?php

$arr = array('apple', 'orange', 'banana');


var_dump(in_array('no i dont have this here!!!', array_keys($arr))); // return true


var_dump(in_array('no i dont have this here!!!', array_keys($arr)), true ); // return false


var_dump(array_key_exists('no i dont have this here!!!', $arr)); // returns false




var_dump( 'no i dont have this here!!!' ); // string(27)




var_dump( (int)'no i dont have this here!!!' ); // int(0)




var_dump( (array_keys($arr)) ) /* Output:

array(3) {

  [0]=>

  int(0)

  [1]=>

  int(1)

  [2]=>

  int(2)

}

*/

Okay, I think I understoof now. in_array() looks something like this.




function in_array($needle, $haystack) {

  foreach ($haystack as $element) {

    if ($needle == $element) 

      return true;

  }

  

  return false;

}



With the values above called in the second iteration there is always "somestring" == 1, which is true, since every non-empty string == 1. However in strict mode the comparison would be "somestring" === 1 which is obviously not true.