PHP变量、方法、类等名称中的有效字符是什么


What are the valid characters in PHP variable, method, class, etc names?

在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

请注意,此正则表达式是逐字节应用的,不考虑编码。这就是为什么它还允许使用许多奇怪的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"

NikiC拥有除函数之外的所有函数。使用变量函数,您可以使用任何您想要的名称,尽管语法很糟糕。

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