mysqli_prepare()用於準備一個SQL 語句,它返回一個mysqli_stmt語句對象。例如:
$mysqli = new mysqli("m66.net", "username", "password", "database");
if ($mysqli->connect_error) {
die("連接失敗: " . $mysqli->connect_error);
}
$sql = "SELECT * FROM users WHERE email = ?";
$stmt = $mysqli->prepare($sql);
if (!$stmt) {
die("預處理失敗: " . $mysqli->error);
}
這裡, ?是參數佔位符,後續會通過bind_param綁定具體值。
mysqli_stmt對象支持一些屬性的獲取和設置,允許控制預處理語句的行為。 PHP 提供了兩個相關方法:
attr_get($attr) :獲取指定屬性的當前值。
attr_set($attr, $value) :設置指定屬性的值。
例如,MySQLi 支持的屬性常量包括:
MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH :控制是否更新最大長度。
MYSQLI_STMT_ATTR_CURSOR_TYPE :設置游標類型(如非游標、只讀游標等)。
MYSQLI_STMT_ATTR_PREFETCH_ROWS :預取的行數。
假設我們想使用游標來處理大量數據,避免一次性加載全部結果集,可以設置游標屬性:
$sql = "SELECT * FROM large_table WHERE category = ?";
$stmt = $mysqli->prepare($sql);
if (!$stmt) {
die("預處理失敗: " . $mysqli->error);
}
// 設置游標類型為 MYSQLI_CURSOR_TYPE_READ_ONLY
$stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY);
// 綁定參數
$category = 'books';
$stmt->bind_param("s", $category);
$stmt->execute();
// 獲取當前游標類型
$currentCursorType = $stmt->attr_get(MYSQLI_STMT_ATTR_CURSOR_TYPE);
echo "當前游標類型是: " . $currentCursorType . PHP_EOL;
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
print_r($row);
}
$stmt->close();
$mysqli->close();
以上示例演示瞭如何在準備語句後設置游標類型,並用attr_get()驗證當前屬性。
在調用execute()之前,盡可能設置所有需要的屬性,比如游標類型、預取行數等,確保執行時能夠生效。
預處理和屬性設置都有可能失敗,務必檢測返回值,並做好錯誤處理,避免運行時崩潰。
游標類型會影響內存和性能,尤其在處理大結果集時,使用只讀游標( MYSQLI_CURSOR_TYPE_READ_ONLY )通常是更優選擇。
某些屬性在老版本MySQL 服務器或PHP 版本中可能不支持,開發時要確認目標環境的支持情況。
合理結合mysqli_prepare()和mysqli_stmt::attr_get 、 attr_set ,可以讓你的數據庫操作更靈活高效,同時保持代碼的安全性。通過設置合適的屬性,尤其是游標和預取行數,可以在處理大數據量時顯著優化性能和資源使用。