PHP - 如何调用在调用上下文外部创建变量的函数?

PHP - Way to call a function that creates variables outside in calling context?

提问人:URi613 提问时间:6/30/2023 更新时间:7/1/2023 访问量:56

问:

我想从提交的表单中提取所有字段的名称,并自动从中创建变量。正如我下面的代码1所示,问题不大。但是我现在想把代码放在一个函数中,我可以从许多PHP表单处理器调用该函数,并让新创建的变量可以在CALLING上下文中访问。下面的代码 2 是我能做的最好的;有没有更安全、更好的方法???

代码1:

foreach($_POST as $key => $value){
   $$key = filter_var($value, FILTER_SANITIZE_STRING);
}
unset($key,$value);

CODE2:(驻留在包含的文件中)

function test(){
        foreach($_POST as $key => $value){
            global $$key; <<<------ my best attempt
            $$key = filter_var($value, FILTER_SANITIZE_STRING);
        }
        unset($key,$value);
}
PHP 函数 变量 scope global

评论

3赞 ADyson 6/30/2023
这类似于 extract 的作用并且是有风险的,正如该文档所说 - 有人可能会提交一个值,该值会覆盖脚本中的另一个重要变量,从而可以在不应该发生的地方注入一些不好的东西。另见 stackoverflow.com/a/11907393/5947043 和类似内容。所以我的建议是,不要从这个(不可控的)客户端输入创建变量名称。为什么你需要呢?只需在需要时直接从 $_POST 访问数据即可。
2赞 ADyson 6/30/2023
附言......这与你的要求相反。这会将全局变量引入局部函数作用域,而不是相反。AFAIK,你不能直接做相反的事情。即使这是一个好主意(它真的不是......见上文),除了从数组中的函数返回值之外,您实际上无能为力。但这实际上只是与 _POST 美元具有相同结构的东西,而且由于 _POST 美元一开始就是一个超级全局,它已经可以从任何地方访问,所以你应该使用它。global $$key; <<<------ my best attempt
0赞 nice_dev 7/1/2023
您更愿意返回一个关联数组并进一步处理它。
0赞 URi613 7/2/2023
抱歉,我遗漏了一些东西,我现在引起了混乱。请放心,我知道旧的超级全局变量方法,以及在没有检查的情况下使用用户输入的风险。在我给出的示例中,在变量到达任何其他位置之前,肯定会有制衡!我的问题是,在不使变量从函数全局的情况下,有没有办法让它们在我的调用代码中使用而不显式返回它们?
0赞 ADyson 7/3/2023
好吧,简单的答案是,不,没有

答:

3赞 Álvaro González 7/1/2023 #1

我想从提交的表单中提取所有字段的名称,并自动从中创建变量。

这实际上从一开始就是PHP bultin的一个功能,由于它很麻烦,最终从语言中删除了它。

如果你对不知从哪里冒出来的变量和能够被黑客入侵的兴奋感到满意,你需要将你的变量添加到$GLOBALS超全局数组中。这将使它们在全球范围内可用。

function test() {
    foreach ($_POST as $key => $value){
        $GLOBALS[$key] = filter_var($value, FILTER_SANITIZE_STRING);
    }
}

有没有更安全、更好的方法???

处理变量列表的最简单方法是使用数组。它也更安全,因为网站访问者无法覆盖随机变量:

function test(): array {
    $sanitized = [];
    foreach ($_POST as $key => $value) {
        $sanitized[$key] = filter_var($value, FILTER_SANITIZE_STRING);
    }
    return $sanitized;
}

但我认为你应该重新考虑你在这里想要完成的事情。 没有做任何有用的事情,也不清楚为什么你不能提前知道你的表单会有什么变量。如果你寻求简单性和安全性,我会投票支持这个:FILTER_SANITIZE_STRING

$foo = $_POST['foo'] ?? null;
$bar = $_POST['bar'] ?? null;

...对于每个变量。替换为您喜欢的任何其他默认值。null

1赞 hakre 7/1/2023 #2

在 CALLING 上下文中可访问新创建的变量。

这很容易。还有一个非常常见的特征:该函数的返回值。

因此,在函数中以 PHP 数组的形式构建变量表,然后返回该数组。

在调用上下文中,然后接收它,并让所有表单变量按其名称作为数组键访问。