您可以在PHP名称中使用哪些有效字符来表示变量,常量,函数,方法,类......?
手册中包含正则表达式[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
的{{3}} some。这个限制什么时候适用,什么时候不适用?
答案 0 :(得分:52)
[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
请注意,此正则表达式是每字节字节应用的,不考虑编码。这就是为什么它allows many weird Unicode names。
但是正则表达式限制仅这些“直接”使用名称。通过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"
答案 1 :(得分:2)
NikiC拥有除功能之外的所有功能。使用变量函数,您可以拥有任何您想要的名称,尽管语法很糟糕。
${'=^^='}=function(){
echo "Hello Kitty!";
};
${'=^^='}(); //outputs "Hello Kitty!"