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

ThinkPHP execute() vs query():核心區別與正確使用場景

     編輯:PHP 相關知識

一句話總結

execute() 執行寫操作(INSERT/UPDATE/DELETE),返回影響行數;
query() 執行讀操作(SELECT),返回數據集陣列。

詳細對比

特性execute()query()
適用 SQLINSERT, UPDATE, DELETE, REPLACE, DDLSELECT, SHOW, DESCRIBE, EXPLAIN
返回值int(影響行數)array(結果集,空時為 [])
執行 SELECT❌ 返回總行數,不返回數據✅ 正常返回數據集
事務支持✅ 可用於事務中❌ 僅讀,不影響事務
預處理綁定✅ 支持✅ 支持

代碼示例

execute() 正確用法

$model = M('MyTable');

// 更新
$affected = $model->execute("UPDATE my_table SET name='aaa' WHERE id=11");
echo "更新了 $affected 行"; // 輸出: 更新了 1 行

// 批量插入
$sql = "INSERT INTO logs (level, message) VALUES " . 
       implode(',', array_fill(0, 100, "(?, ?)"));
$data = [];
foreach (range(1, 100) as $i) {
    $data[] = 'INFO';
    $data[] = "Log message $i";
}
$model->execute($sql, $data); // 預處理防注入

query() 正確用法

$model = M('MyTable');

// 簡單查詢
$users = $model->query("SELECT id, name, email FROM users WHERE status=1 LIMIT 20");
// 返回: [['id'=>1,'name'=>'Tom','email'=>'tom@...'], ...]

// 複雜統計
$stats = $model->query("
    SELECT DATE(created_at) as day, COUNT(*) as cnt 
    FROM orders 
    WHERE created_at > DATE_SUB(NOW(), INTERVAL 30 DAY)
    GROUP BY day
    ORDER BY day DESC
");

錯誤示範

// ❌ 用 execute 執行 SELECT
$model->execute("SELECT * FROM users"); // 返回總行數,無法獲取數據

// ❌ 用 query 執行 UPDATE
$model->query("UPDATE users SET last_login=NOW()"); // 返回空數組,無法知曉影響行數

底層原理

  • execute() 內部調用 `PDO::exec()` 或 `mysqli_query()` 後獲取 `affected_rows`
  • query() 內部調用 `PDO::query()` / `mysqli_query()` 後 `fetchAll()` 獲取全部結果集
  • 兩者均支持參數綁定:`$model->execute("UPDATE ... WHERE id=?", [$id])`

最佳實踐建議

  1. 語義化命名:代碼審查時,看到 `execute` 即知為寫操作,`query` 為讀操作
  2. 事務邊界:多條 `execute` 需包裹在 `$model->startTrans()` / `$model->commit()` 中
  3. 大數據集:`query()` 會一次性載入所有結果到內存,超大結果集改用游標或分批處理
  4. ORM 優先:簡單 CRUD 優先用 `M()->where()->save()` / `select()`,僅複雜 SQL 直寫

ThinkPHP 5.0+ 更新

TP5 引入 `Db::execute()` / `Db::query()` 靜態調用,並新增 `Db::listen()` SQL 監聽、`Db::getLastSql()` 調試,核心語義不變。

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