Почему функция `key ()` не вызывает предупреждения или ошибки при использовании с объектом вместо массива? - PullRequest
2 голосов
/ 13 февраля 2020

При работе с массивами довольно просто использовать array_keys() для захвата ключей вашего массива. При работе с объектами у нас есть другие функции, такие как get_object_vars() для их обработки.

Так что, если у нас есть две простые переменные, один массив и один объект:

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

Если мы возьмем функцию array_keys() и передадим ей массив, он сделает то, что мы все ожидаем, и даст нам массив с foo, john и beep:

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

И, конечно, как и ожидалось, если мы вместо этого передадим ему объект , функция взорвется и не будет знать, что с ним делать (если нам это действительно нужно, мы можем преобразовать или даже просто типизировать его). к массиву):

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

Но если мы имеем дело с одним ключом за раз, это, кажется, становится немного более интересным. Используя функцию PHP key(), мы можем извлечь любой ключ, какой захотим.

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"

Глядя на документацию для функции key(), разве это не выдает предупреждение, если используется object? Я спрашиваю, потому что мне любопытно, и мне недавно отказали и сказали не использовать key() на объектах. Обычно я использую другие методы, но в некоторых случаях использовал key() без предупреждений (или ошибок) - поэтому я решил посмотреть, и нигде в документации ничего не говорится о разрешении object, просто array &$array. Я полагаю, что подобное можно сказать и о функциях указателя массива, таких как end().

1 Ответ

1 голос
/ 13 февраля 2020

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

Если объект преобразуется в массив, результатом является массив, элементы которого являются свойствами объекта. Ключи являются именами переменных-членов, с несколькими заметными исключениями: целочисленные свойства недоступны; закрытые переменные имеют имя класса, добавленное к имени переменной; Защищенные переменные имеют «*» перед именем переменной. Эти предварительно добавленные значения имеют нулевые байты с обеих сторон. Это может привести к неожиданному поведению

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


Кроме того, в зависимости от того, является ли данное свойство public / protected / private, вы можете не получить ожидаемый доход.

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

...