[英]Passing $_POST/$_GET as a parameter to function
我遇到了一段有趣的 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 是一個全局變量?
一個完整的遠景:他們是否可以對此做出任何善意的“后來的補充”(例如我的例子),這幾乎可以證明這種做法是合理的,或者這只是一種誤解。 或者是否存在可以證明這種做法合理的安全隱患?
恕我直言,這是一種抽象的做法,並且有以下好處:
通用性:通過接收$_POST
作為參數,函數與$_POST
耦合變得不那么緊密。 該功能可以服務於更多場景並且可能更可重用。
控制反轉:因為函數的依賴( $_POST
)是從外部注入的,所以你對函數有更多的控制權。 這有點不太可能,但讓我們假設您的表單已更新,現在您需要通過 GET 方法提交。 在不修改函數體的情況下,在調用方傳入$_GET
就足以反映更改。
測試夾具隔離:為了模擬 FORM 輸入來測試函數中的某個代碼路徑,最好以抽象的方式訪問全局狀態(例如$_POST
),這樣測試本身不會給其他部分帶來副作用系統。
一般來說,有一個很好的理由傳遞$_POST
或$_GET
或任何你想要的數組作為參數,而不是通過自動全局變量訪問它。 它被稱為“依賴注入” ,它是可測試代碼的一個關鍵特性。
另一個不使用自動全局變量(或全局變量)的原因是代碼的可讀性。
相比:
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
。
在將 $_POST Superglobal 作為函數的參數傳遞之前對其進行清理是一個好主意,然后將它轉義到具有查詢邏輯的函數中。
他所做的是通過mysqli_real_escape_string函數轉義每個 POST 變量,這確保您避免 SQL 注入攻擊。然后他通過調用返回數組(帶有轉義值): return $vars;
他可能使用了一個函數來執行此操作,因為他打算在整個應用程序中多次重復這些步驟,並且他可能只是調用該函數並傳遞變量,而不是一遍又一遍地編寫代碼。
在進行任何數據庫調用之前,請確保您始終退出用戶輸入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.