Подтвердить что ты не робот

Почему ${0x0} правильный?

Следующий код работает отлично:

${0x0} = 'test';
echo ${0x0}; // prints "test"

Но я не могу понять, почему. 0x0 (или 0, как не-шестнадцатеричные люди называют его) является случайным контейнером, это могло быть любое число, но php-переменные не могут начинаться с числа. Что здесь такого особенного в { }, и каковы их ограничения?

4b9b3361

Ответ 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"