PHP中的变量变量允许非法变量名称?

时间:2017-03-29 10:14:59

标签: php variables

我发现PHP语言中似乎是一个可以滥用的错误。在创建变量变量时,只要您继续将其作为变量变量访问,就可以声明并处理看似非法的变量。 例如:

${'0'} = 1;         //I am an illegal variable called $0
${'0'}++;           //I can be accessed and manipulated.
var_dump(${'0'});   //Output: int(2)

这种行为看起来很奇怪。在SimpleXml的官方文档中简要提到了创建包含连字符的变量名称的方法,但是我的示例显示它可能会被滥用得非常糟糕。

我想知道为什么这种行为是可行的并且在解析代码时可以容忍?

2 个答案:

答案 0 :(得分:3)

内部PHP stores variableszend_array* symbol_table)位于用于arrays的相同数据结构中。这允许您使用与数组键相同的约束来使用变量名。

EG。 Zend API函数zend_set_local_var使用zend_hash_update为符号表设置一个值,这是一个用于操作PHP数组类型的函数。

但是我们不能在PHP源代码中允许变量名中的每个字符。这是因为词法分析必须将标签与其他标记区分开来。变量为此提供了一种解决方法。

这不是一个错误,也不是滥用任何东西的方法。话虽如此,documentation声明所有标签(包括变量)必须具有正则表达式[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*,因此我不会依赖变量名中的任意字符。

${'0'} = 1;实际上做了什么,它将值1设置为键0处的当前范围的符号表。 您可以使用get_defined_vars函数获取该特定表。 查看source code,我们会看到该函数只复制当前符号表并将其返回给调用者。

PHP extract函数src实际检查密钥是否具有有效的标签格式(通过调用php_valid_var_name),因此您无法使用它生成带有时髦名称的变量。

无论如何,即使可以使用变量语法(甚至是没有名称${''}的变量)创建任何名称的变量,我认为这是不好的做法。更糟糕的是,如果图书馆期望或强制执行此操作。说它的解决方法实际上可能有点夸大其词。也许它应该被视为一个实现细节和一个未记录的功能。

答案 1 :(得分:0)

@Nadav我对此并不完全了解,但有点想法,

请记住,花括号({})字面意思是“评估花括号内的内容”,所以,你可以像你一样挤压变量创建$ {'0'} = 1 从http://php.net/manual/en/language.variables.php#73373

中提到了它

PHP以数组形式存储变量,如果要检查然后使用$ GLOBALS(数组)是超全局变量,它具有脚本中存在的变量的所有引用,它将变量名称存储为键和值作为变量值,假设如下:

<?php
    ${'0'} = 1; // here php stores it as 0th index in the array
    ${'1'} = 2; // here php stores it as 1th index in the array
    $b = "I am b"; // here php stores it as bth index in the array
    echo "<pre>";
    print_r($GLOBALS);
  

输出:

Array
(
    [_GET] => Array
        (
        )

    [_POST] => Array
        (
        )

    [_COOKIE] => Array
        (
        )

    [_FILES] => Array
        (
        )

    [GLOBALS] => Array
 *RECURSION*
    [0] => 1
    [1] => 2
    [b] => I am b
)