首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

ThinkPHP 驗證碼 Session 過期邏輯重構:Date 對象與字符串類型不匹配修正

     編輯:程式設計綜合問答

原代碼核心缺陷

$Setime = $Date->dateAdd(...);  // 返回 Date 對象
session('time', $Setime);       // 存入 Session
// 後續讀取
$diff = $Date->dateDiff("$Setime", "s"); // 隱式轉換為字符串,邏輯錯亂

類型不匹配:存入的是 Date 對象,取出後直接用於字符串比較/日期運算,導致邏輯判斷失效。

修正版代碼

public function myses() {
    import("ORG.Util.Date");
    $Setime = session('time');
    $Date = new Date;
    
    if ($Setime !== null) {
        // 關鍵修正:Session 存儲格式化字符串
        $diff = $Date->dateDiff($Setime, "s");
        if ($diff <= 0) { // 過期判斷:差值 <= 0 表示已過期
            $Setime = $Date->dateAdd(60, "s"); // 60 秒有效期
            session('time', $Setime->format()); // 存字符串
            session('rand', rand(11111, 99999));
            return session('rand');
        } else {
            return session('rand'); // 未過期直接返回
        }
    } else {
        $Setime = $Date->dateAdd(60, "s");
        session('time', $Setime->format()); // 存字符串
        session('rand', rand(11111, 99999));
        return session('rand');
    }
}

關鍵修正點

  1. 存入 Session 前調用 format():統一存儲「YYYY-MM-DD HH:II:SS」格式字符串
  2. 過期判斷邏輯反轉:dateDiff 返回剩餘秒數,<=0 表示過期
  3. 統一返回值:所有分支 return session('rand'),調用者直接獲取驗證碼
  4. 有效期調整:示例改為 60 秒,生產環境建議 300 秒 (5 分鐘)

更佳實踐:ThinkPHP 內置驗證碼類

// 控制器
public function verify() {
    $config = ['length' => 4, 'expire' => 300]; // 5 分鐘過期
    $verify = new \Think\Verify($config);
    $verify->entry();
}

// 模板
<img src="__CONTROLLER__/verify" onclick="this.src='__CONTROLLER__/verify?'+Math.random()" />

// 驗證
$verify = new \Think\Verify();
if (!$verify->check($_POST['verify_code'])) {
    $this->error('驗證碼錯誤');
}

框架內置組件經過大量生產驗證,優先使用而非手寫 Session 邏輯。若必須自定義,嚴格統一「存字符串、取字符串、運算轉對象」類型紀律。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved