Почему ${0x0} правильный?
Следующий код работает отлично:
${0x0} = 'test';
echo ${0x0}; // prints "test"
Но я не могу понять, почему. 0x0
(или 0
, как не-шестнадцатеричные люди называют его) является случайным контейнером, это могло быть любое число, но php-переменные не могут начинаться с числа. Что здесь такого особенного в { }
, и каковы их ограничения?
Ответы
Ответ 1
Прежде всего, 0x0
является просто регулярным 0
в шестнадцатеричном представлении, которое получает приведение в строку '0
'при использовании с синтаксисом переменной переменной:
var_dump(0x0===0); // prints "bool(true)"
${0x0} = 'test';
echo ${0x0}; // prints "test"
echo ${'0'}; // prints "test" as well
var_dump(get_defined_vars()); // contains ["0"] => string(4) "test"
Вы правы, вы говорите, что это не допустимое имя переменной:
Переменные имена соответствуют тем же правилам, что и другие метки в PHP. Действительный имя переменной начинается с буквы или подчеркивания, за которой следует любое количество букв, цифр или символов подчеркивания. Как регулярное выражение, это было бы выражено следующим образом: "[a-zA-Z_\x7f-\xff] [a-zA-Z0-9_\x7f-\xff] * '
Вот почему $0foo = 'Test';
вызывает ошибку синтаксического анализа.
Некоторые быстрые тесты с синтаксисом переменных переменных показывают, что на самом деле PHP, похоже, действительно не заботится об именах переменных, поскольку они являются строками:
${'123 abc xyz '} = 'Test';
echo ${'123 abc xyz '}; // Test
echo ${'123 abc xyz '}; // PHP Notice: Undefined variable: 123 abc xyz in ...
var_dump(get_defined_vars()); // ["123 abc xyz "] => string(4) "Test"
Мое предположение заключается в том, что вышеупомянутое ограничение имен накладывается парсером исходного кода, а не ядром языка. Он нуждается в таких правилах, чтобы анализировать переменные отдельно при анализе кода PHP. Внутренний механизм Zend, который поддерживает PHP обрабатывает переменные как хэш-карту:
PHP-переменные, в общем, состоят из двух вещей: ярлык, который например, может быть запись в таблице символов, а фактическая переменный контейнер.
Итак, насколько он получает правильную строку для ярлыка, он счастлив.
Ответ 2
Из документации:
Также можно использовать фигурные скобки, чтобы четко разграничить имя свойства. Они наиболее полезны при доступе к значениям в свойстве, содержащем массив, когда имя свойства составлено из нескольких частей или , когда имя свойства содержит символы, которые в противном случае не действительны (например, из json_decode() или SimpleXML).
Для меня это означает, что если вы используете ${...}
, нет никаких ограничений относительно того, какие символы могут использоваться в имени переменной. Однако, если вы...
Ответ 3
Другими словами, все в фигурных скобках в таких случаях является строкой!
Итак, s 0x0
действительно является шестнадцатеричной версией 0
, но здесь обе строки! Вот почему работают ${0x0}
или ${0}
, где $0
или $0x0
не будет!
Ответ 4
Парсер PHP предоставляет специальный синтаксис для создания имени переменной из любого выражения, которое возвращает строку (или может быть отправлено в строку), например:
<?php
define('A', 'aaa');
${' _ '} = 'blah';
${'test' . A . (2 + 6)} = 'var';
echo ${' _ '}; // blah
echo ${'testaaa8'}; // var
${'123'} = 'blah';
echo ${100 + 23}; // blah
function returnVarName() {
return 'myVar';
}
$myVar = 12;
echo ${returnVarName()}; // 12
Этот синтаксис также доступен для свойств объекта:
$object->{' some property ... with strage name'};
0x0
- это просто шестнадцатеричное представление литерала 0
.
Ответ 5
В дополнение к тому, что сказал Майкл Робинсон, в вашем примере это также будет действительным:
${0x0} = 'test';
$var = "0";
echo $$var; // prints "test"