Home » Php » php – Why doesn't the `key()` function trigger warnings or errors when used with an object instead of an array?

php – Why doesn't the `key()` function trigger warnings or errors when used with an object instead of an array?

Posted by: admin February 25, 2020 Leave a comment

Questions:

When dealing with arrays, it’s quite trivial to use array_keys() to grab the keys of your array. When dealing with objects, we have other functions like get_object_vars() to handle those.

So if we have two simple variables, one array and one object:

+--------------------+---------------------------+
|       Array        |          Object           |
+--------------------+---------------------------+
| $array = array(    | $object = new stdClass(); |
|   'foo'  => 'bar', |                           |
|   'john' => 'doe', | $object->foo  = 'bar';    |
|   'beep' => 'bop'  | $object->john = 'doe';    |
| );                 | $object->beep = 'bop';    |
+--------------------+---------------------------+

If we take the array_keys() function and pass it the array, it does what we all expect and gives us an array with foo, john, and beep:

Return: array(3) {
  [0]=> string(3) "foo"
  [1]=> string(4) "john"
  [2]=> string(4) "beep"
}

And of course, as expected, if we instead pass the object to it, the function explodes and doesn’t know what to do with it (if we really needed to, we could convert or even just typecast it to an array):

Return: NULL
WARNING array_keys() expects parameter 1 to be array, object given

But if we’re dealing with a single key at a time, it seems to get a little bit more interesting. Using PHP’s key() function, we can extract whatever key we want.

key($array); //returns: string(3) "foo"
key($object); //returns: string(3) "foo"

// If we move the internal pointer
end( $array ); // key($array) returns: string(4) "beep"
end( $object ); // key($object) returns: string(4) "beep"

Looking at the documentation for the key() function, should this not throw up a warning if an object is used? I ask because I’m curious and was recently downvoted and told not to use key() on objects. Generally I use other methods, but have used key() in some instances without warnings (or errors) – and so I decided to look and nowhere does the documentation say anything about allowing an object, just array &$array. I suppose a similar thing could be said the the array pointer functions like end().

How to&Answers:

From: https://www.php.net/manual/en/language.types.array.php

If an object is converted to an array, the result is an array whose elements are the object’s properties. The keys are the member variable names, with a few notable exceptions: integer properties are unaccessible; private variables have the class name prepended to the variable name; protected variables have a ‘*’ prepended to the variable name. These prepended values have null bytes on either side. This can result in some unexpected behaviour

For this reason, it should be considered unreliable in certain scenarios to rely on the keys not being mutated in the conversion.


Furthermore, depending on if a given property is public/protected/private, then you might not get the return you expect.

https://www.php.net/manual/en/function.get-object-vars.php#47075