Php 将$\u POST/$\u GET作为参数传递给函数

Php 将$\u POST/$\u GET作为参数传递给函数,php,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","my

我遇到了一段有趣的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);
这让我想到了为什么有人想把$\u POST作为变量传递,而不直接在函数内部访问它?我能想到的唯一好处(这有点遥不可及)是,如果我们在调用函数之前将其他信息附加到$\u POST中(例如:

然而,守则中没有任何证据表明这种做法。只需调用
do\u something()
,并将
$\u POST
作为一个片段传递

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


一个完整的远景:他们是否有可能对这一做法(比如我的例子)做出任何善意的“后续补充”,几乎可以证明这种做法是正确的,或者这只是一种误解。或者可能有一种安全性暗示可以证明这种做法是正确的?

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

他可能使用了一个函数来实现这一点,因为他打算在整个应用程序中多次重复这些步骤,他可能只是调用该函数并传递变量,而不是反复编写代码


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

这是一种抽象实践,有以下好处:

  • 通用性:通过将
    $\u POST
    作为参数接收,函数与
    $\u POST
    的耦合变得不那么紧密。该功能可以服务于更多的场景&可能更易于重用

  • 控制反转:因为函数的依赖项(
    $\u POST
    )是从外部注入的,所以您对函数有更多的控制权。这不太可能,但假设您的表单已经更新,现在您需要通过GET方法提交。在不修改函数体的情况下,在调用者一侧传入
    $\u GET
    ,就足以反映更改

  • 测试夹具隔离:为了模拟表单输入来测试函数中的特定代码路径,最好以抽象的方式访问全局状态(例如
    $\u POST
    ),这样测试本身就不会给系统的其他部分带来副作用


  • 一般来说,传递
    $\u POST
    $\u GET
    或任何您想要的数组作为参数,而不是通过自动全局变量访问它,这是一个很好的理由。它被称为,是可测试代码的一个关键特性

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

    比较:

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

    在第一种情况下,函数
    do\u something()。你不必阅读函数的代码就能知道这一点;所有相关信息都显示在函数标题和示例用法中

    在第二种情况下,函数
    do\u something\u else()
    的行为取决于
    $\u POST
    的内容,但如果不查看其代码,就无法知道这一点


    回到您发布的代码,它看起来不像是在考虑可测试性的情况下编写的

    只看一下:

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

    它基本上可以用更多的词来表达。

    在将$\u post Superglobal作为函数的参数传递之前,最好先对其进行清理,然后在具有查询逻辑的函数中对其进行转义。

    这是毫无意义的,试图更好地完成php的老版本“死了/走了/没有错过”
    magic_quotes
    所做的工作——假设所有发布到php的内容都只会在sql查询上下文中使用。我认为这项工作使该函数更具通用性,也许开发人员试图将依赖性外部化,以便对功能进行单元测试?对于这个看似不必要的特殊功能,但对于实际的业务逻辑来说,它是有意义的。该代码中的原始错误是首先选择
    mysqli
    over
    PDO
    。在使用预先准备好的语句时,您不需要这种变通方法——这恰好是PDO所能容忍的。@ScottMcGready:当有人真的喜欢他们的锤子时,一切看起来都像钉子。您完全没有抓住问题的关键。我不是要澄清代码的作用。。。我已经知道了。我在问为什么有人会选择将
    $\u POST
    作为参数传递,而不是直接在函数中访问它。因为函数是一组可以多次使用的通用代码。他可能还想将该函数用于其他数据..例如$_getarray,custom array等..但我假设您已经超越了函数的角色我理解函数是什么,谢谢,我问了一个具体的问题。其他答案已经说明了为什么某人可以通过<代码> $POST 或<代码> $$GET VARS作为函数的参数,就像你在评论中提到的那样。我对你所说的“但我认为你已经超越了函数的角色”感到困惑。。。什么?1似乎可以理解。2不太可能,但仍然是个好主意。3似乎是这里最有可能的候选。将此标记为答案,因为它提供了一些选项,说明了原始作者的意图。我知道您来自何处,但函数顶部有一个巨大的docblock,描述了它如何使用$\u POST vars执行x。。。我想我只是继承了一个烂摊子!
    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);
    
    foreach($_POST as $post_key => $post_value){
        $post[$post_key] = $post_value;
    }