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

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

Каковы допустимые символы, которые вы можете использовать в именах PHP для переменных, констант, функций, методов, классов,...?

В руководстве указано упоминание регулярного выражения [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*. Когда это ограничение применяется, а когда нет?

4b9b3361

Ответ 1

Регулярное выражение [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 magic:

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"

Ответ 2

В NikiC есть все, кроме функций. С переменными функциями вы можете иметь любое имя, которое хотите, хотя синтаксис сосет.

${'=^^='}=function(){
   echo "Hello Kitty!";
};

${'=^^='}(); //outputs "Hello Kitty!"