簡體   English   中英

在MVC網站上驗證和處理表單提交的位置

[英]Where to validate and process form submission in MVC website

我正在開發一個基於PHP的Model-View-Controller結構化網站。 我知道模型應該處理業務邏輯,視圖向用戶呈現HTML(或其他形式),並且控制器可以簡化此過程。 我遇到問題的地方是表格。 我要對控制器進行多少處理,我要對模型進行多少處理?

假設我正在嘗試更新用戶的名字和姓氏。 我要做的是使用AJAX向我的一個控制器提交一個表單。 我希望數據(再次)在服務器端進行驗證,如果有效,則將其保存到數據庫中,然后將JSON響應返回為成功或錯誤,返回視圖。

我應該在控制器中創建用戶模型的實例,還是僅讓控制器中繼到模型中的靜態方法? 這是兩個如何工作的示例:

選項1:在模型中處理POST

<form action="/user/edit-user-form-submit/" method="post">
    <input type="text" name="firstname">
    <input type="text" name="lastname">
    <button type="submit">Save</button>
</form>

<?php
    class user
    {
        public function __construct($id){} // load user from database
        public function set_firstname(){} // validate and set first name
        public function set_lastname(){} // validate and set last name
        public function save_to_database(){} // save object fields to database

        public static function save_data_from_post()
        {
            // Load the user
            $user = new user($_POST['id']);

            // Was the record found in the db?
            if($user->exists)
            {
                // Try to set these fields
                if(
                    $user->set_firstname($_POST['firstname'])
                    and
                    $user->set_lastname($_POST['lastname'])
                )
                {
                    // No errors, save to the dabase
                    $user->save_to_database();

                    // Return success to view
                    echo json_encode(array('success' => true));
                }
                else
                {
                    // Error, data not valid!
                    echo json_encode(array('success' => false));
                }
            }
            else
            {
                // Error, user not found!
                echo json_encode(array('success' => false));
            }
        }   
    }

    class user_controller extends controller
    {
        public function edit_user_form()
        {
            $view = new view('edit_user_form.php');
        }
        public function edit_user_form_submit()
        {
            user::save_data_from_post();
        }
    }
?>

選項1:在模型中處理POST

<form action="/user/edit-user-form-submit/" method="post">
    <input type="text" name="firstname">
    <input type="text" name="lastname">
    <button type="submit">Save</button>
</form>

<?php
    class user
    {
        public function __construct($id){} // load user from database
        public function set_firstname(){} // validate and set first name
        public function set_lastname(){} // validate and set last name
        public function save_to_database(){} // save object fields to database
    }

    class user_controller extends controller
    {
        public function edit_user_form()
        {
            $view = new view('edit_user_form.php');
        }
        public function edit_user_form_submit()
        {
            // Load the user
            $user = new user($_POST['id']);

            // Was the record found in the db?
            if($user->exists)
            {
                // Try to set these fields
                if(
                    $user->set_firstname($_POST['firstname'])
                    and
                    $user->set_lastname($_POST['lastname'])
                )
                {
                    // No errors, save to the dabase
                    $user->save_to_database();

                    // Return success to view
                    echo json_encode(array('success' => true));
                }
                else
                {
                    // Error, data not valid!
                    echo json_encode(array('success' => false));
                }
            }
            else
            {
                // Error, user not found!
                echo json_encode(array('success' => false));
            }
        }
    }
?>

我意識到,這兩個示例完全相同。 但是,這樣做有對與錯的方法嗎? 我已經讀了很多關於瘦控制器和胖模型的信息,選項1是從哪里來的。 您如何處理? 謝謝,對於很長的問題感到抱歉!

簡而言之,您可以使用這兩種方法中的任何一種- 您應該對其進行一些更改。

考慮一下:這些模型並不真正“知道”發布,獲取以及諸如此類的東西。 他們應該只知道與他們有關的任何與業務相關的事物-在您的情況下是用戶。

因此,雖然可以使用方法#1,你應該從模型直接訪問后變量。 取而代之的是,使函數采用一組參數,然后使用這些參數來創建用戶。

這樣,您可以輕松地重用代碼,例如在shell腳本等中,沒有$_POST類的東西。

盡管第二種方法在控制器中更為冗長,但是您也可以這樣做。 但是,這種樣式中也許更好的方法是使用“服務類”。 該服務將具有一個方法,例如“ createUserFromArray”,該方法采用一個數組並返回一個用戶。 同樣,您可以將$_POST作為參數傳遞給此方法-類似於將它們傳遞給修改后的#1中的函數的方式。

僅控制器應直接處理輸入。 這是因為控制器處理請求,因此可以知道有關發布的信息。

tl; dr,您的模型永遠不應直接使用$_POST類的超全局變量。

從我的觀點以及我們在工作中的工作方式來看,模型將處理傳遞給它的數據的驗證和過濾,但是我們使用控制器將選擇的數據推入模型中。

在上面的注釋中已經說明,模型不必知道$ _POST或$ _GET這些是控制器必須處理的用戶輸入。 另一方面,該模型必須處理所有傳遞給它的數據的驗證,因為您絕對不想在項目的不同代碼部分中一次又一次地進行數據驗證。

MVC設計模式的一個重要原因是它是維護關注分離的好方法。 視圖應忽略模型,反之亦然。 控制器僅作為在模型和視圖之間進行調解的一種交通方式。 因此,控制器應從視圖中獲取數據,進行所需的最少處理,以便模型無需了解視圖的實現方式(即通過HTML表單)即可理解數據,並將其提供給模型,以便模型可以保留數據。

這樣,當需要通過HTML表單以外的其他方式創建/保存/保存項目時,可以在其他實例中重用該模型,而無需在多個Controller之間復制保存項目的代碼。

更新:我忘了提到驗證。 沿着與保留數據相同的方式,控制器應獲取數據並將其傳遞給模型進行驗證,因為模型是知道所需數據確切格式的模型。 您可以通過在數據無效的情況下讓Model引發異常來組合驗證和持久性,Controller可以根據需要捕獲並處理該異常(例如,呈現JSON錯誤響應)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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