将$ _POST / $ _ GET作为参数传递给函数

时间:2015-08-31 17:08:02

标签: php

我遇到了一段有趣的PHP代码,让我有点难过为什么作者选择这样做。

function do_something($db, $post_vars){
    foreach($post_vars as $key => $value{
        $vars[$key] = mysqli_real_escape_string($db, $value);
    }
    return $vars;
}

$db = mysqli_connect("myhost","myuser","mypassw","mybd") or die("Error " . mysqli_error($link)); 
do_something($db, $_POST);

让我想到为什么有人想要将$ _POST作为变量传递而不是直接在函数内部访问它?我能想到的唯一好处(这是一个长镜头)是我们在调用函数之前将其他信息附加到$ _POST(例如):

function do_something($db, $post_vars){
    foreach($post_vars as $key => $value{
        $vars[$key] = mysqli_real_escape_string($db, $value);
    }
    return $vars;
}

$db = mysqli_connect("myhost","myuser","mypassw","mybd") or die("Error " . mysqli_error($link)); 

foreach($_POST as $post_key => $post_value){
    $post[$post_key] = $post_value;
}

$post['my_custom_var'] = "a";

do_something($db, $post);
然而,在代码中的任何地方都没有证据表明这种做法。只需拨打do_something()$_POST即可作为广告传递。

我的问题是,这样做有什么好处,我错过了或者作者根本不明白$ _POST是一个全局变量?

一个完整的远景:是否有任何好的预期"后来添加"他们可以做到这一点(例如我的例子)几乎证明这种做法是正当的,或者这只是一个误解的例子。或者是否存在可以证明这种做法的安全含义?

4 个答案:

答案 0 :(得分:4)

恕我直言,这是一种抽象的做法,并且有好处:

  1. 一般性:通过接收$_POST作为参数,函数与$_POST的耦合程度降低。该功能可以用于更多场景和可能更可重复使用。

  2. 控制反转:因为函数的依赖关系($_POST)是从外部注入的,所以你可以更好地控制函数。这有点不太可能,但我们假设您的表单已更新,现在您需要通过GET方法提交。在不修改功能体的情况下,在呼叫者旁边传递$_GET就足以反映这一变化。

  3. 测试夹具隔离:要模拟FORM输入以测试函数中的某个代码路径,最好以抽象的方式访问全局状态(例如$_POST),以便测试本身可以不要给系统的其他部分带来副作用。

答案 1 :(得分:2)

通常,有一个很好的理由将$_POST$_GET或任何你想要的数组作为参数传递,而不是通过自动全局变量访问它。它被称为"dependency injection",它是可测试代码的关键功能。

不使用自动全局变量(或一般的全局变量)的另一个原因是代码的可读性。

比较

function do_something($db, array $post_vars) {
    // many lines of code here, you don't want to read them
}

do_something($db, $_POST);

function do_something_else($db) {
    // many lines of code here that use $_POST, you don't want to read them either
}

do_something_else($db);

在第一种情况下,它明确表示函数do_something()$_POST(或$_GET或其他任何数据充满数据的值进行操作,并将其作为参数传递给它。你不必阅读函数的代码就知道了;所有相关信息都显示在功能标题和示例用法中。

在第二种情况下,函数do_something_else()的行为取决于$_POST的内容,但如果不查看其代码就无法知道。

回到您发布的代码,它看起来并没有考虑到可编辑性。

只看一下:

foreach($_POST as $post_key => $post_value){
    $post[$post_key] = $post_value;
}

更多的话,它基本上都是$post = $_POST

答案 2 :(得分:0)

最好先清理$ _POST超全局变量,然后再将其作为函数的参数传递,然后将其转义到具有查询逻辑的函数中。

答案 3 :(得分:-2)

他所做的是通过mysqli_real_escape_string函数转义每个POST变量,这样可以避免SQL注入攻击。然后通过调用返回数组(带有转义值):return $ vars;

他可能已经使用了一个函数来执行此操作,因为他打算在整个应用程序中多次重复这些步骤,他可能只是调用该函数并传递变量而不是一遍又一遍地编写代码。

请确保在进行任何数据库调用之前始终退出用户输入。