PHP 後端表單驗證和請求處理

2021-03-02 xueyuanjun

創建好前端的聯繫表單視圖後,接下來,我們來編寫提交表單後後端的 PHP 處理邏輯。

數據表和模型類

我們會將用戶提交的請求數據保存到 messages 表中,所以我們需要在資料庫中新增這張數據表:

--
-- 資料庫: `blog`
--

-- -

--
-- 表的結構 `messages`
--

CREATE TABLE `messages` (
  `id` int UNSIGNED NOT NULL,
  `name` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
  `email` varchar(100) COLLATE utf8mb4_general_ci NOT NULL,
  `phone` varchar(20) COLLATE utf8mb4_general_ci NOT NULL,
  `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `created_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='消息表';

然後在 blog 項目的 app/model 目錄下新建對應的模型類 Message:

<?php
namespace App\Model;

use Illuminate\Database\Eloquent\Model;

class Message extends Model
{
    public $timestamps = false;
}

表單數據處理邏輯

做好上述準備後,接下來,我們在 HomeController 控制器的 contact 方法中,編寫表單數據獲取、驗證和保存代碼:

public function contact()
{
    if ($this->request->getMethod() == 'GET') {
        // 聯繫表單頁面
        ...
    } else {
        // POST 提交表單處理邏輯
        $name = $this->request->get('name');
        $email = $this->request->get('email');
        $phone = $this->request->get('phone');
        $content = $this->request->get('message');
        // 驗證表單輸入數據
        if (empty($name)) {
            throw new ValidationException('用戶名不能為空');
        }
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new ValidationException('請輸入正確的郵箱地址');
        }
        if (!preg_match('/^1[34578]{1}\d{9}$/', $phone)) {
            throw new ValidationException('請輸入正確的手機號碼');
        }
        if (empty($content)) {
            throw new ValidationException('消息內容不能為空');
        }
        $message = new Message();
        $message->name = filter_var($name, FILTER_SANITIZE_STRING);
        $message->email = $email;
        $message->phone = $phone;
        $message->content = filter_var($content, FILTER_SANITIZE_STRING);
        $message->created_at = Carbon::now();
        if ($message->save()) {
            (new Response('消息保存成功', 200))->send();
        }
        (new Response('保存消息失敗,請重試!', 500))->send();
    }
}

這裡,我們通過 $this->request->get 方法獲取表單請求數據,然後對這些表單數據進行簡單的驗證,比如用戶名和消息內容不能為空、郵箱格式必須合法(使用 PHP 內置的 filter_var 方法進行過濾,該方法通過傳入的第二個驗證過濾器常量參數對變量值進行驗證,還可以支持 IP、URL 等其他字符串格式的校驗)、手機號符合正則匹配規則,如果驗證不通過會拋出 ValidationException 異常,關於異常響應的處理,我們稍後會介紹。

如果所有請求數據通過驗證,就可以通過 Message 模型類實例將其保存到資料庫中了。這裡,對於用戶名和消息內容,我們還調用了 filter_var 方法,並在第二個參數傳入「消毒」過濾器常量參數對其進行處理,以避免字符串中包含 HTML 標籤,出現 XSS 攻擊隱患。

因此,filter_var 函數可以根據傳入的第二個參數標識進行不同的操作,既可以用於欄位驗證,也可以用作消毒處理,還可以通過回調函數進行額外的自定義操作,更多細節請參考 PHP 官方文檔關於該函數的介紹。

消息保存成功後,我們通過 Response 對象發送響應給客戶端。

異常響應處理

在測試表單請求處理邏輯之前,我們來介紹下對異常響應的處理。

在上面的代碼中,當請求欄位驗證失敗後,會拋出 ValidationException 異常(該異常類定義在 app/http/exception 目錄下):

<?php
namespace App\Http\Exception;

class ValidationException extends \Exception
{

}

此時,程序就終止了,不能繼續往後執行了,那麼這種情況下該如何將異常信息發送給客戶端呢?

這裡,我們可以藉助之前在 PHP 錯誤和異常處理教程中介紹的全局異常處理器來捕獲程序中拋出的所有未處理異常,進行兜底處理。

打開 app/bootstrap.php 文件,在裡面定義一個註冊全局異常處理器的方法:

// 註冊全局異常處理器
function registerExceptionHandler()
{
    set_exception_handler(function ($exception) {
        $response = new Response();
        if ($exception instanceof ValidationException) {
            $response->setStatusCode(422);
            $response->setContent($exception->getMessage());
        } else {
            $response->setStatusCode(500);
            $response->setContent( '伺服器異常');
        }
        $response->send();
    });
}

我們通過 set_exception_handler 註冊全局異常處理器,在定義異常處理邏輯的回調函數中,可以看到,如果捕獲到的異常是 ValidationException 實例,則將響應狀態碼設置為 422,然後通過 Response 響應實例發送驗證錯誤信息給客戶端,對於其他異常,目前先統一返回 500 錯誤。

最後在啟動應用的 bootApp 方法中,調用這個註冊全局異常處理器的 registerExceptionHandler 方法即可:

/**
 * 啟動應用
 * @param Container $container
 * @return Container
 */
function bootApp(Container $container)
{
    registerExceptionHandler();
    ...
}

在聯繫表單頁面發起請求

至此,我們就完成了 POST 表單請求的所有後端處理邏輯,在瀏覽器打開聯繫表單頁面,如果輸入了錯誤的手機號,會返回對應的驗證錯誤消息:

如果所有表單數據都通過驗證,則會看到消息發送成功提示:

當然,這裡還有可以優化的地方,比如,在請求數據驗證失敗後,返回提交的請求數據填充對應的輸入框,以免用戶重新輸入。

訪問資料庫,在 messages 表中應該可以看到最新插入的記錄:

這樣,完整的前後端表單請求功能就完成了,博客前端功能也就告一段落了,下篇教程,學院君會給大家如何純手工搭建博客後臺管理系統。

(全文完)

長按下面的二維碼,即可訂閱學院君最新發布的 PHP 入門到實戰系列教程:

關於本系列教程的更多動態,請點擊頁面左下角的「閱讀原文」連結查看。

相關焦點

  • 實戰jQuery和PHP CodeIgniter表單驗證
    【IT168 專稿】        前言  在Web建站中,表單的合法性驗證是十分重要的一個環節,其中包括客戶端瀏覽器的Javascript的驗證和服務端的驗證。
  • PHP教程:用PHP程序對網頁表單的處理
    PHP _GET 和 _POST變量是用來獲取表單中的信息的,比如用戶輸入的信息。PHP表單操作在我們處理HTML表單和PHP表單時,我們要記住的重要一點是:HTML頁面中的任何一個表單元素都可以自動的用於PHP腳本:表單舉例:
  • 使用React和HTML5表單驗證API處理表單
    在本教程中,我們將看看如何使用React和HTML5的現代組合來處理表單提交和驗證。當我們在Web應用程式中討論用戶輸入時,我們經常首先想到HTML表單。Web表單從HTML的第一個版本開始就已經可用。顯然,該功能已於1991年推出,並在1995年以RFC 1866標準進行了標準化。
  • 15個最佳的 JavaScript 表單驗證庫
    客戶端驗證在任何項目都是不夠的,因為 Java 可以直接忽略,人們可以提交請求到伺服器。 然而這並不意味著客戶端驗證都沒必要了,很多時候我們需要在用戶提交到伺服器之前給予提示。Java 表單驗證庫允許開發人員自定義樣式、錯誤消息和樣式以及簡化驗證規則的創建。在本文中,您將找到最好的15個 Java 表單驗證庫,可以幫助你讓表單驗證對用戶更友好的和美觀。
  • (實用篇)php常用表單驗證類
    php/*** 頁面作用:常用表單驗證類*/class class_post{//驗證是否為指定長度的字母/數字組合function fun_text1($num1,$num2,$str){     return (preg_match("/^[a-zA-Z0-9]{".
  • PHP之表單的提交
    phpecho "提交成功";提交結果:說明:(1)、密文提交方式,提交在http協議內部。如何模擬:凡是html文檔中能夠輸入url的地方,再所請求的文件名後加上?名=值&名=值方式向後臺傳遞數據 。
  • python前端和後端數據交互,tornado框架入門,初學小試牛刀!
    Python前端和後端是如何交互的,怎麼用tornado框架快速搭建前端和後端數據交互?前端與後端的數據交互,最常用的就是GET、POST,比較常用的用法是:提交表單數據到後端,後端返回json前端的數據發送與接收1)提交表單數據2)提交JSON數據後端的數據接收與響應
  • 使用Html+JavaScript實現表單上用戶名和密碼的非空驗證案例
    ,因此,表單驗證是JavaScript的鼻祖功能。我們可以將在C#後端開發中使用的一些表單驗證技巧用在JavaScript表單驗證中。語言不同,但原理都是一樣的。目標:練習JavaScript給文本框賦值和取值,並進行非空判斷。
  • PHP高級之一次請求處理過程或生命周期詳解
    >PHP總共有三個模塊:內核、Zend引擎、以及擴展層;PHP內核用來處理請求、文件流、錯誤處理等相關操作;Zend引擎(ZE)用以將源文件轉換成機器語言,然後在虛擬機上運行它;擴展層是一組函數、類庫和流,PHP使用它們來執行一些特定的操作
  • PHP代碼安全
    水平越權水平越權就是同等角色下的用戶,不但能夠訪問和操作自己私有的數據,還能訪問其他人私有的數據,其根本是基於數據的訪問權限。如在找回密碼過程中,攻擊者使用自己的帳戶信息通過驗證,將他人的密碼進行了修改。graph LR1.郵箱驗證-->2.找回密碼在步驟1之後,執行找回密碼,路由為 。如果此時沒有校驗當前找回密碼的帳戶是否為進行郵箱校驗後的帳戶,由可能產生越權漏洞.
  • PHP實例:用PHP實現表單驗證碼登陸校驗
    首頁 > 語言 > 關鍵詞 > php最新資訊 > 正文 PHP實例:用PHP實現表單驗證碼登陸校驗
  • 【PHP專題8】表單-用戶輸入名字,發送服務端接收數據
    b、另外一個網頁接收用戶註冊,並且把用戶輸入名字和email傳遞過去代碼實現一、POST發送表單步驟1:代碼很簡單,在body標籤做一個表單注意:一定在php程序外面寫程序講解:10行就是php輸出標題
  • Zebra_Form 2.0 發布,PHP的表單類
    Zebra_Form 是一個 PHP 類用於簡化表單的創建和數據驗證。 示例代碼: <?phprequire 'path/to/Zebra_Form.php';$form = new Zebra_Form('form');$form->add('label', 'label_email
  • 2017最熱門的PHP框架,順便推薦幾個視頻教程
    許多PHP開發者選擇PHP框架,就是因為在PHP框架中為你的應用已經提供了精準的目錄和環境,便於快捷開發。這也是一個開發高擴展性和高質量網頁的最佳實踐。在過去幾年中,Lavarel有很明顯的優勢一直處在最熱門PHP框架的冠軍位置,同樣在2016年也是如此。現在我們也越來越多講開發邏輯轉移到前端,後端只是作為一個API。
  • 讓你喜歡的八個 PHP 網頁爬蟲庫與工具
    使用Symfony Panther的有用提示:當開發腳本出現錯誤處理方法,Panther是在埠9515上運行Chrome,可以使用BASH命令kill $(lsof -t -i:9515),就可以發現殺死它並使腳本恢復正常工作。
  • PHP(Laravel)用戶註冊、登錄和退出
    實現用戶登陸註冊在其他的 PHP 框架中,如果要實現登陸註冊、表單驗證、記住密碼、多次登陸鎖定帳戶、發郵件重置密碼這一系列功能,這是一個非常繁瑣的事情,就算是非常有經驗的老手,實現起來也需要花費不少功夫,想想都很頭疼。那麼這些功能,在 laravel 中實現,需要多久呢?
  • PHP代碼安全有必要了解下
    水平越權水平越權就是同等角色下的用戶,不但能夠訪問和操作自己私有的數據,還能訪問其他人私有的數據,其根本是基於數據的訪問權限。如在找回密碼過程中,攻擊者使用自己的帳戶信息通過驗證,將他人的密碼進行了修改。graph LR1.郵箱驗證-->2.找回密碼在步驟1之後,執行找回密碼,路由為 。如果此時沒有校驗當前找回密碼的帳戶是否為進行郵箱校驗後的帳戶,由可能產生越權漏洞.
  • HTML5時代 實戰PHP之Web頁面表單設計
    HTML5在頁面結構,多媒體處理等多方面都與以往的HTML有很大的不同。在本教程中,將帶領大家使用HTML5,CSS3及PHP實際設計一個符合HTML5標準的簡單的表單提交網頁,讀者可以從中學習到HTML5 新的表單頁面的基本元素。
  • PHP如何使用郵箱找回密碼?
    2、當用戶忘記密碼或用戶名時,點擊登錄頁面的「找回密碼」超連結,打開表單,並輸入註冊用的 email 郵箱,提交。3、系統通過該郵箱,從資料庫中查找到該用戶信息,並更新該用戶的密碼為一個臨時密碼(比如:123456)。
  • 學會使用HTML5 和 JavaScript優化表單驗證
    全文共3663字,預計學習時長11分鐘表單驗證是使用HTML5時的一個內置特性,HTML5提供了各種驗證屬性。作為瀏覽器端HTML和JavaScript的一部分。在將數據發送到伺服器之前,我們可以使用它來驗證表單輸入。