我遇到了一段有趣的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是一个全局变量?
一个完整的远景:是否有任何好的预期"后来添加"他们可以做到这一点(例如我的例子)几乎证明这种做法是正当的,或者这只是一个误解的例子。或者是否存在可以证明这种做法的安全含义?
答案 0 :(得分:4)
恕我直言,这是一种抽象的做法,并且有好处:
一般性:通过接收$_POST
作为参数,函数与$_POST
的耦合程度降低。该功能可以用于更多场景和可能更可重复使用。
控制反转:因为函数的依赖关系($_POST
)是从外部注入的,所以你可以更好地控制函数。这有点不太可能,但我们假设您的表单已更新,现在您需要通过GET方法提交。在不修改功能体的情况下,在呼叫者旁边传递$_GET
就足以反映这一变化。
测试夹具隔离:要模拟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;
他可能已经使用了一个函数来执行此操作,因为他打算在整个应用程序中多次重复这些步骤,他可能只是调用该函数并传递变量而不是一遍又一遍地编写代码。
请确保在进行任何数据库调用之前始终退出用户输入。