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

PHP mysqli 查詢在命令行/phpMyAdmin 正常,代碼中返回 false 排查實錄

     編輯:程式設計綜合問答

故障現場

$sql = "select * from $table_list where $length_left qq $length_right $textif $t;";
$mysqli = new mysqli("localhost","root","root",'qq_db');
$mysqli->set_charset("utf8");
$result = $mysqli->query($sql);
var_dump($result); // 輸出 bool(false)

實際 SQL 輸出:select * from qq_list where length( qq = 5) and qq like '%1%' and wuzheng;

排查步驟與根因

  1. 直接輸出 SQL 並複製到 phpMyAdmin 執行 → 成功返回結果,說明 SQL 語法、數據、權限無問題。
  2. 檢查 PHP 變量拼接:$length_left、$length_right 等變量來源不明,疑似包含隱形字符(如  、全角空格、零寬空格)。
  3. 關鍵發現:變量值中混入 HTML 實體  (不換行空格),導致拼接後 SQL 含不可見字符,MySQL 解析報錯但 mysqli->query() 僅返回 false 不拋異常。
  4. 修復:
    - 變量賦值前 str_replace(' ', '', $var) 或 html_entity_decode()。
    - 統一使用**預處理語句**避免拼接注入與編碼問題:
$stmt = $mysqli->prepare("SELECT * FROM qq_list WHERE LENGTH(qq) = ? AND qq LIKE ? AND wuzheng = 1");
$stmt->bind_param("is", $len, $like);
$len = 5;
$like = "%1%";
$stmt->execute();
$result = $stmt->get_result(); // 需 mysqlnd 驅動
while ($row = $result->fetch_assoc()) { ... }

核心教訓

  • 永不信任拼接 SQL:預處理語句(Prepared Statement)同時解決注入、編碼、類型轉換三大問題。
  • 變量來源清理:從 HTML/POST/GET/SESSION 獲取的字符串,必須 trim()、html_entity_decode()、去除零寬字符(preg_replace('/[\x{200B}-\x{200D}\x{FEFF}]/u', '', $str))。
  • 錯誤處理規範:
    if (!$result) { error_log($mysqli->error); throw new Exception('Query failed: '.$mysqli->error); }
    不要只 var_dump($result) 靠肉眼看 bool(false)。

驗證清單

// 1. 開啟 mysqli 異常模式(PHP 8.1+ 默認開啟)
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

// 2. 統一字符集
$mysqli->set_charset("utf8mb4"); // 支持 emoji

// 3. 使用預處理
$stmt = $mysqli->prepare("SELECT * FROM ? WHERE ...); // 注意:表名不能參數化,需白名單驗證

從「拼接字符串」遷移到「預處理 + 異常模式」,是 PHP 連接 MySQL 專業化的分水嶺。

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