Каковы допустимые символы в именах PHP, методах, классах и т. Д.?

Каковы допустимые символы, которые вы можете использовать в именах 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!"