Что означает оператор PHP → {...}?
Недавно я увидел эту строку в фрагменте кода PHP:
$dbObject = json_decode($jsonString);
$dbObject->{'mysql-5.4'}[0]->credentials
Что это значит? В PHP docs мы можем прочитать, что
Оба квадратных скобки и фигурные скобки могут использоваться взаимозаменяемо для доступа к элементам массива (например, $array [42] и $array {42} будут делать то же самое в примере выше).
Но как определить объект $dbObject, чтобы разрешить доступ к ->{...}[...]
? Является ли этот код небезопасным? Какая версия PHP позволяет это?
Я пропустил что-нибудь в документах PHP?
Ответы
Ответ 1
Это, чтобы разрешить доступ к свойствам, которые были бы недопустимым синтаксисом в виде простых литералов. Значение:
$dbObject->mysql-5.4[0]->credentials
Это недопустимый/неоднозначный синтаксис. Чтобы понять PHP, что mysql-5.4
- это свойство, а не свойство минус float, вам нужно использовать синтаксис {'..'}
.
Чтобы быть точным, ->{..}
позволяет использовать любое выражение в качестве имени свойства. Например:
$dbObject->{ sprintf('%s-%.1f', 'mysql', 5.4) }
Ответ 2
Синтаксис фигурных фигурных скобок в примере не является синтаксисом массива, а исходит из возможного синтаксиса для доступа к переменным с именами переменных.
Также можно использовать фигурные скобки, чтобы четко разграничить имя свойства. Они наиболее полезны при доступе к значениям в пределах свойства, которое содержит массив, когда имя свойства составлено из нескольких частей, или когда имя свойства содержит символы, которые иначе (например, из json_decode() или SimpleXML).
Примеры из документов PHP:
echo $foo->{$baz[1]} . "\n";
echo $foo->{$start . $end} . "\n";
echo $foo->{$arr[1]} . "\n";
См. "Переменные переменных PHP": http://php.net/manual/en/language.variables.variable.php
(Дополнительные примеры использования там...)
Ответ 3
В качестве дополнения к @deceze answer:
Оператор ->
означает, что вы получаете доступ к свойству объекта. В этом случае имя свойства должно быть mysql-5.4
, которое не является допустимым идентификатором PHP (оно должно содержать буквы, цифры или символы подчеркивания, см. здесь), Таким образом, на 100% уверен, что имя свойства было создано динамически.
PHP позволяет перегружать свойства с помощью магического метода __get()
. Тело этого метода позволяет вам обрабатывать любое свойство, которое вы пожелаете - это может быть любая строка или любая переменная, даже объект, который передается в строку.
Итак, в вашем случае кто-то создал класс с магическим методом __get()
, который обрабатывает строку mysql-5.4
. Фигурные фигурные скобки {
и }
даны для обозначения того, что строка должна рассматриваться как имя свойства (однако нет свойства с этим именем).
Ответ 4
Синтаксис фигурной скобки позволяет использовать строковый литерал или переменную в качестве имени свойства или метода.
Это полезно по нескольким причинам:
-
(для каждого ответа @Deceze): он позволяет вам обращаться к именам свойств, которые иначе не были бы действительными синтаксисом PHP - например, если имя свойства содержит точку или тире в вашем примере. Обычно такие свойства можно получить с помощью магического метода __get()
, так как они также были бы недопустимым синтаксисом для определения как фактического свойства внутри класса.
-
(за ответ @feela): он позволяет использовать переменные для ссылки на ваши свойства. Это похоже на синтаксис переменной переменной $$
. Это вообще не очень хорошая практика, но полезно в некоторых случаях.
-
(еще не упомянуто другими ответами): он позволяет удалить определенные потенциальные двусмысленности из вашего кода. Рассмотрим следующий код, например:
$output = $foo->$bar['baz'];
Это неоднозначно. Вы можете устранить двусмысленность, добавив фигурные скобки или скобки:
$output = $foo->{$bar['baz']}; //gets the value of a property from $foo which has a name that is defined in $bar['baz']
$output = ($foo->$bar)['baz']; //gets the ['baz'] element of $foo->$bar array.
Это особенно важно, потому что предстоящий relese PHP 7 изменит поведение кода по умолчанию, как будто. Это заставит язык вести себя более последовательно, но нарушит существующий код, который не имеет фигурных скобок.
См. также документацию PHP для этого изменения здесь: https://wiki.php.net/rfc/uniform_variable_syntax
Но даже без изменения языка, чтобы заставить проблему, такой код должен иметь брекеты в любом случае, чтобы помочь с удобочитаемостью - если вы не поместите фигурные скобки, то вы можете в конечном итоге изо всех сил пытаться понять, что вы пытаетесь сделать когда вы вернетесь к коду через шесть месяцев.