簡體   English   中英

將 $_POST/$_GET 作為參數傳遞給函數

[英]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 是一個全局變量?

一個完整的遠景:他們是否可以對此做出任何善意的“后來的補充”(例如我的例子),這幾乎可以證明這種做法是合理的,或者這只是一種誤解。 或者是否存在可以證明這種做法合理的安全隱患?

恕我直言,這是一種抽象的做法,並且有以下好處:

  1. 通用性:通過接收$_POST作為參數,函數與$_POST耦合變得不那么緊密。 該功能可以服務於更多場景並且可能更可重用。

  2. 控制反轉:因為函數的依賴( $_POST )是從外部注入的,所以你對函數有更多的控制權。 這有點不太可能,但讓我們假設您的表單已更新,現在您需要通過 GET 方法提交。 在不修改函數體的情況下,在調用方傳入$_GET就足以反映更改。

  3. 測試夾具隔離:為了模擬 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM