Каковы допустимые символы, которые вы можете использовать в именах PHP для переменных, констант, функций, методов, классов, …?
В руководстве есть некоторые упоминания о регулярном выражении [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
. Когда это ограничение применяется, а когда нет?
[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
применяется только тогда, когда имя используется непосредственно в каком-то специальном синтаксическом элементе. Некоторые примеры:
$varName // <-- varName needs to satisfy the regex $foo->propertyName // <-- propertyName needs to satisfy the regex class ClassName {} // <-- ClassName needs to satisfy the regex // and can't be a reserved keyword
Обратите внимание, что это регулярное выражение применяется byte-by-byte без учета кодирования. Вот почему он также позволяет много странных имен Unicode .
Но регулярное выражение ограничивает только эти «прямые» использования имен. Благодаря различным динамическим функциям PHP позволяет использовать практически произвольные имена.
В общем случае вы не должны делать никаких предположений о том, какие символы могут содержать имена символов в PHP. В большинстве случаев это просто произвольные строки. Выполнение таких вещей, как «проверка достоверности имени какого-либо класса», просто бессмысленно в PHP.
Далее я приведу примеры того, как вы можете создавать странные имена для разных категорий.
Имена переменных могут быть произвольными строками:
${''} = 'foo'; echo ${''}; // foo ${"\0"} = 'bar'; echo ${"\0"}; // bar
Глобальные константы также могут быть произвольными строками:
define('', 'foo'); echo constant(''); // foo define("\0", 'bar'); echo constant("\0"); // bar
Невозможно динамически определять константы класса, о которых я знаю, поэтому они не могут быть произвольными. Единственный способ создания странных констант класса, по-видимому, состоит из кода расширения.
Свойства не могут быть пустой строкой и не могут начинаться с байта NUL, но кроме этого они произвольны:
$obj = new stdClass; $obj->{''} = 'foo'; // Fatal error: Cannot access empty property $obj->{"\0"} = 'foo'; // Fatal error: Cannot access property started with '\0' $obj->{'*'} = 'foo'; echo $obj->{'*'}; // foo
Имена методов произвольны и могут обрабатываться магией __call
:
class Test { public function __call($method, $args) { echo "Called method \"$method\""; } } $obj = new Test; $obj->{''}(); // Called method "" $obj->{"\0"}(); // Called method "\0"
Произвольные имена классов могут быть созданы с использованием class_alias
за исключением пустой строки:
class Test {} class_alias('Test', ''); $className = ''; $obj = new $className; // Fatal error: Class '' not found class_alias('Test', "\0"); $className = "\0"; $obj = new $className; // Works!
Я не знаю, как создать произвольные имена функций из userland, но есть еще некоторые случаи, когда внутренний код создает «странные» имена:
var_dump(create_function('','')); // string(9) "\0lambda_1"
У NikiC есть все, кроме функций. С переменными функциями вы можете иметь любое имя, которое хотите, хотя синтаксис сосет.
${'=^^='}=function(){ echo "Hello Kitty!"; }; ${'=^^='}(); //outputs "Hello Kitty!"