預處理語句是一種SQL 查詢的執行方式。它將SQL 查詢分為兩個部分:
預處理階段:發送SQL 語句的模板給數據庫,數據庫解析並編譯這個SQL 語句,但不執行查詢。這時,查詢中的變量部分(例如用戶輸入的內容)不會立即插入到SQL 中,而是以佔位符(通常是? )表示。
執行階段:在執行時,通過綁定實際的參數值來替代佔位符,再由數據庫執行該語句。
這種方法的好處在於,數據庫能夠預先準備查詢,並且對每個查詢的參數進行安全的驗證,從而避免了SQL 注入的風險。
在PHP 中,我們通過mysqli擴展來操作MySQL 數據庫,而mysqli_stmt::__construct是mysqli_stmt類的一個構造函數,用於創建一個預處理語句。
步驟概述:
建立數據庫連接:首先需要使用mysqli_connect或new mysqli()創建數據庫連接。
準備SQL 語句:定義帶有佔位符的SQL 語句。
初始化預處理語句:使用mysqli_prepare或mysqli_stmt::__construct創建預處理語句。
綁定參數:使用bind_param方法將變量值綁定到預處理語句中的佔位符。
執行語句:使用execute方法執行預處理語句。
假設我們要向一個用戶表插入用戶數據,包含姓名、電子郵件和年齡,我們使用mysqli_stmt::__construct來創建一個預處理語句。以下是具體的代碼示例:
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 1. 創建數據庫連接</span></span><span>
</span><span><span class="hljs-variable">$servername</span></span><span> = </span><span><span class="hljs-string">"localhost"</span></span><span>;
</span><span><span class="hljs-variable">$username</span></span><span> = </span><span><span class="hljs-string">"root"</span></span><span>;
</span><span><span class="hljs-variable">$password</span></span><span> = </span><span><span class="hljs-string">""</span></span><span>;
</span><span><span class="hljs-variable">$dbname</span></span><span> = </span><span><span class="hljs-string">"test"</span></span><span>;
</span><span><span class="hljs-variable">$conn</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli</span></span><span>(</span><span><span class="hljs-variable">$servername</span></span><span>, </span><span><span class="hljs-variable">$username</span></span><span>, </span><span><span class="hljs-variable">$password</span></span><span>, </span><span><span class="hljs-variable">$dbname</span></span><span>);
</span><span><span class="hljs-comment">// 檢查連接</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$conn</span></span><span>->connect_error) {
</span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">"Connection failed: "</span></span><span> . </span><span><span class="hljs-variable">$conn</span></span><span>->connect_error);
}
</span><span><span class="hljs-comment">// 2. 定義帶佔位符的 SQL 語句</span></span><span>
</span><span><span class="hljs-variable">$sql</span></span><span> = </span><span><span class="hljs-string">"INSERT INTO users (name, email, age) VALUES (?, ?, ?)"</span></span><span>;
</span><span><span class="hljs-comment">// 3. 创建预处理語句</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span> = </span><span><span class="hljs-variable">$conn</span></span><span>-></span><span><span class="hljs-title function_ invoke__">prepare</span></span><span>(</span><span><span class="hljs-variable">$sql</span></span><span>);
</span><span><span class="hljs-comment">// 檢查預處理是否成功</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$stmt</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">'Error preparing statement: '</span></span><span> . </span><span><span class="hljs-variable">$conn</span></span><span>->error);
}
</span><span><span class="hljs-comment">// 4. 綁定參數</span></span><span>
</span><span><span class="hljs-variable">$name</span></span><span> = </span><span><span class="hljs-string">"John Doe"</span></span><span>;
</span><span><span class="hljs-variable">$email</span></span><span> = </span><span><span class="hljs-string">"[email protected]"</span></span><span>;
</span><span><span class="hljs-variable">$age</span></span><span> = </span><span><span class="hljs-number">25</span></span><span>;
</span><span><span class="hljs-comment">// "sss" 表示綁定的變量類型,分別對應字符串、字符串、整數</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">bind_param</span></span><span>(</span><span><span class="hljs-string">"ssi"</span></span><span>, </span><span><span class="hljs-variable">$name</span></span><span>, </span><span><span class="hljs-variable">$email</span></span><span>, </span><span><span class="hljs-variable">$age</span></span><span>);
</span><span><span class="hljs-comment">// 5. 执行预处理語句</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">execute</span></span><span>()) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"New record created successfully"</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Error: "</span></span><span> . </span><span><span class="hljs-variable">$stmt</span></span><span>->error;
}
</span><span><span class="hljs-comment">// 关闭語句和连接</span></span><span>
</span><span><span class="hljs-variable">$stmt</span></span><span>-></span><span><span class="hljs-title function_ invoke__">close</span></span><span>();
</span><span><span class="hljs-variable">$conn</span></span><span>-></span><span><span class="hljs-title function_ invoke__">close</span></span><span>();
</span><span><span class="hljs-meta">?></span></span><span>
</span></span>創建數據庫連接:使用new mysqli()方法連接數據庫,如果連接失敗,程序會停止並顯示錯誤信息。
SQL 語句:定義一個帶有佔位符的SQL 語句INSERT INTO users (name, email, age) VALUES (?, ?, ?) 。這裡的?是佔位符,表示我們將通過後續步驟動態插入數據。
準備語句:通過$conn->prepare($sql)方法創建一個預處理語句。如果創建失敗,會輸出錯誤信息。
綁定參數: $stmt->bind_param("ssi", $name, $ email , $age)方法將變量$name 、 $email和$age綁定到SQL 語句中的?佔位符。 "ssi"表示參數的數據類型, s是字符串(string), i是整數(integer)。
執行語句:通過$stmt->execute()執行預處理語句。如果執行成功,會返回成功信息,否則輸出錯誤。
關閉資源:執行完畢後,需要關閉預處理語句和數據庫連接,釋放資源。
防止SQL 注入:通過使用佔位符而非直接拼接SQL 語句,能夠有效防止惡意用戶通過輸入特殊字符進行SQL 注入攻擊。
提高性能:如果你要多次執行相同的查詢(例如批量插入數據),使用預處理語句比每次都重新解析SQL 語句要高效得多。
代碼更清晰:使用預處理語句可以使代碼結構更清晰,尤其是在涉及用戶輸入和多次查詢時,能夠減少SQL 拼接錯誤的機會。
相關標籤:
mysqli_stmt