PHP 变量变量未覆盖原始变量

PHP variable variable not overriding original variable

我正在尝试使用可变变量覆盖我的 PHP 文件中的一些变量,但我得到了意想不到的结果,其中原始值永远不会被覆盖,但新的变量-变量值具有唯一性来自其原始变量对应值的值。

$case1 = (time() > strtotime('11/22/2020 07:00:00:000AM'));
$case2 = (time() > strtotime('11/16/2020 07:00:00:000AM'));
$case3 = (time() > strtotime('12/01/2020 12:00:00:000PM'));
$case4 = (time() > strtotime('04/24/2021 05:00:00:000AM'));
if (!empty($_GET['schedule_test'])) { $$_GET['schedule_test'] = true; }

如果有人访问页面路径 /?schedule_test=case4,上面的行应该覆盖变量 $case4,因为 $_GET['schedule_test'] 等于 case4 使得语句 $$_GET['schedule_test'] = true 相当于 $case4 = true.

但是,即使访问 URL 路径 /?schedule_test=case4,我仍然得到 $case4 的值 false。我 var_dumped $case4$$_GET['schedule_test'] 的值,它们的值不同:

echo $case4; // false
echo $$_GET['schedule_test']; // true

期望的目标是能够在任何设定时间内测试这四种情况中的任何一种,并将 URL 参数 schedule_test 设置为任何变量名称(例如 case1, case2, case3, case4).

PHP documentation

In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second.

所以,你应该使用

${$_GET['schedule_test']}

但是,我强烈建议不要直接使用用户输入来决定像这样编写哪个变量。允许攻击者更改代码的内部行为的风险非常高。

因为 $_GET 是一个数组,你不能使用 $$ 来访问 $_GET 的值并获取变量,这与 PHP 内部解析器不知道你是否想要访问 $$_GET 然后是键或 $_GET 键然后是变量,这在示例 #1 以上的 variable variables 三段文档中进行了讨论。要解决此问题,您必须用大括号将 $_GET 括起来。

if (! empty($_GET['schedule_test'])) {
    ${$_GET['schedule_test']} = true;
}

echo $case4;
echo ${$_GET['schedule_test']};