首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

CodeIgniter 購物車類不支持中文商品名的根因與修復方案

     編輯:PHP 相關知識

CodeIgniter 購物車類不支持中文商品名的根因與修復方案

CodeIgniter 內置 Cart 庫在驗證商品名稱時,默認正則僅允許 ASCII 字符,導致中文商品名添加失敗。本文定位源碼位置,提供最小侵入性修復方案,並說明正則修改原則。

問題現象

$this->load->library('cart');
$this->cart->insert([
    'id'      => 'sku_001',
    'name'    => '中文商品名', // 包含中文
    'price'   => 99,
    'qty'     => 1
]);
// 返回 false,日誌記錄:An invalid name was submitted as the product name...

根因定位

文件:system/libraries/Cart.php (CI 3.x) 約第 186-190 行:

if ( ! preg_match("/^[".$this->product_name_rules."]+$/i", $items['name'])) {
    log_message('error', 'An invalid name was submitted as the product name: '.$items['name'].' The name can only contain alpha-numeric characters, dashes, underscores, colons, and spaces');
    return FALSE;
}

默認配置 $this->product_name_rules = ':\w\d\s\-\_'; (或類似),正則字符類不包含中文 Unicode 範圍。

修復方案(按推薦順序)

方案一:修改配置屬性(最優雅,無需動核心庫)

在控制器或 MY_Cart 擴展類中重置 product_name_rules:

<?php
class MY_Cart extends CI_Cart {
    public function __construct() {
        parent::__construct();
        // 允許:字母、數字、中文、下劃線、連字符、冒號、空格、括號、常見標點
        $this->product_name_rules = 'a-zA-Z0-9\u4e00-\u9fa5\s\-\_\:\.\,\(\)\(\)';
    }
}
// 控制器中正常載入 $this->load->library('cart'); 會自動加載 MY_Cart
?>
  • 優點:不修改框架核心文件,升級無衝突,集中維護規則。
  • 注意:正則需在 [] 內轉義特殊字符,\u4e00-\u9fa5 需 PHP 開啟 u 修飾符支持(CI 內部 preg_match 已加 i,需確認是否加 u,建議改用 [\x{4e00}-\x{9fa5}] 並顯式加 u 修飾符,或直接擴展 preg_match 調用)。

方案二:直接修改核心庫正則(快速但不推薦長期維護)

// system/libraries/Cart.php 第 186 行附近
// 原:"/^[".$this->product_name_rules."]+$/i"
// 改:支持中文的正則 (需 u 修飾符)
if ( ! preg_match("/^[\w\d\s\-\_\:\.\,\x{4e00}-\x{9fa5}]+$/iu", $items['name'])) {
    // ...
}
  • 缺點:框架升級覆蓋、團隊協作易衝突、違反「不修改核心」原則。

方案三:預處理商品名(繞過驗證)

// 控制器插入前
$name = $this->input->post('name');
$safe_name = urlencode($name); // 或 base64_encode
$this->cart->insert(['name' => $safe_name, ...]);
// 讀取時 urldecode/base64_decode
// 缺點:增加編解碼開銷、數據庫存儲不直觀、搜索/報表受影響


正則修改原則與最佳實踐

  1. 白名單原則:明確列出允許的字符集合,而非嘗試過濾危險字符。
  2. 最小權限:僅允許業務真正需要的字符(如商品名通常不需要 <>"' 等)。
  3. Unicode 範圍:中文基本區 \u4e00-\u9fa5、擴展區 \u3400-\u4dbf、標點 \u3000-\u303f。建議使用 [\p{Han}\p{L}\p{N}\s\-\_\:\.\,\(\)\(\)] (需 u 修飾符) 覆蓋所有漢字、字母、數字。
  4. 測試用例:覆蓋純中文、中英混合、含特殊標點、極長名稱、XSS 嘗試 (<script>) 等。

驗證修復

$this->load->library('cart');
$test_cases = [
    '純中文商品',
    'English Product',
    '中英混合 Product 123',
    '特殊符號:、。,()',
    '<script>alert(1)</script>', // 應被攔截或轉義
];
foreach ($test_cases as $name) {
    $result = $this->cart->insert(['id'=>uniqid(), 'name'=>$name, 'price'=>10, 'qty'=>1]);
    echo $name . ' => ' . ($result ? '成功' : '失敗') . "\n";
}

採用 方案一 (MY_Cart 擴展) + Unicode 白名單正則,即可徹底解決中文商品名問題,且保持代碼可維護性與安全性。

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