mysqli_stmt類:使用預處理語句處理SELECT查詢結果


SELECT語句和其他的SQL查詢命令不同,它需要處理查詢結果。SQL語句的執行也需要使用mysqli_stmt對象中的execute()方法,但與mysqli對象中的query()方法不同,execute()方法的返回值並不是一個mysqli_result對象。mysqli_stmt對象提供了一種更為精巧的辦法來處理SELECT語句查詢結果:在使用execute()方法執行SQL語句完成查詢之后,使用mysqli_stmt對象中的bind_result()方法,把查詢結果的各個數據列綁定到一些PHP變量上;然后使用mysqli_stmt對象中的fetch()方法把下一條結果記錄讀取到這些變量里。如果成功地讀入下一條記錄fetch()方法返回TRUE,否則返回FALSE,或者已經讀完所有的結果記錄返回FALSE。

默認情況下,SELECT查詢結果將留在MySQL服務器上,等待fetch()方法把記錄逐條取回到PHP程序中,賦給使用bind_result()方法綁定的PHP變量上。如果需要對所有記錄而不只是一小部分進行處理,可以調用mysqli_stmt對象中的store_result()方法,把所有結果一次全部傳回到PHP程序中。這樣做不僅更有效率,而且能減輕服務器的負擔。store_result()方法是可選的,除了讀取數據不改變任何東西。以聯系人信息表contactinfo為例,使用預處理語句處理SELECT查詢結果的代碼如下所示:

<?php
$mysqli = new mysqli("localhost", "mysql_user", "mysql_pwd", "demo");       // 連接MySQL數據庫
if (mysqli_connect_errno())
{
    // 檢查連接錯誤
    printf(“連接失敗: %s<br>”, mysqli_connect_error());
    exit();
}
 
$query = "SELECT `name`, `address`, `phone` FROM `contactinfo` LIMIT 0,3";  // 聲明SELECT語句
if ($stmt = $mysqli->prepare($query))
{
    // 處理打算執行的SQL命令
    $stmt->execute();
 
    // 執行SQL語句
    $stmt->store_result();
 
    // 取回全部查詢結果
    echo "記錄個數:".$stmt->num_rows."行<br />";
 
    // 輸出查詢的記錄個數
    $stmt->bind_result($name, $address, $phone);
 
    // 當查詢結果綁定到變量中
    while ($stmt->fetch())
    {
        // 逐條從MySQL服務取數據
        printf ("%s (%s,%s)<br />", $name, $address, $phone);     //格式化結果輸出
    }
 
    $stmt->close();
    //釋放mysqli_stmt對象占用的資源
}
 
$mysqli->close();
//關閉與MySQL數據庫的連接
?>

輸出結果如下所示:

  1. 記錄個數:3行
  2. 高某某 (海淀區,15801688338)
  3. 洛某某 (朝陽區,15801681234)
  4. 峰某某 (東城區,15801689876)

如果獲取SELECT語句查找到了多少條記錄,可以從mysqli_stmt對象中的num_rows屬性中檢索出來。但是,這個屬性只有在提前執行過store_result()方法,將全部查詢結果傳回到PHP程序中的情況下才可以使用。

如果在SELECT語句中也使用占位符號(?),並需要多次執行這一條語句時,也可以將mysqli_stmt對象中的bind_param()和bind_result()方法結合起來使用。代碼如下所示:

<?php
$mysqli = new mysqli("localhost", "mysql_user", "mysql_pwd", "demo");   // 連接MySQL數據庫
if (mysqli_connect_errno())
{
    // 檢查連接錯誤
    printf("連接失敗: %s<br>", mysqli_connect_error());
    exit();
}
 
// 聲明SELECT語句,按部門編號查找,使用占位符號(?)表示將要查找的部門
$query = "SELECT `name`, `address`, `phone` FROM `contactinfo` WHERE `departmentId`=? LIMIT 0,3";
if ($stmt = $mysqli->prepare($query))
{
    // 處理打算執行的SQL命令
    $stmt->bind_param('s', $departmentId);
 
    // 綁定參數部門編號
    $departmentId = "D01";
 
    // 給綁定的變量賦上值
    $stmt->execute();
 
    // 執行SQL語句
    $stmt->store_result();
 
    // 取回全部查詢結果
    $stmt->bind_result($name, $address, $phone);
 
    // 當查詢結果綁定到變量中
    echo "D01部門的聯系人信息列表如下:<br />";
 
    // 打印提示信息
    while ($stmt->fetch())
    {
        // 逐條從MySQL服務取數據
        printf ("%s (%s,%s)<br />", $name, $address, $phone);     // 格式化結果輸出
    }
 
    echo "D02部門的聯系人信息列表如下:<br />";
 
    // 打印提示信息
    $departmentId = "D02";
 
    // 給綁定的變量賦上新值
    $stmt->execute();
 
    // 執行SQL語句
    $stmt->store_result();
 
    // 取回全部查詢結果
    while ($stmt->fetch())
    {
        // 逐條從MySQL服務取數據
        printf ("%s (%s,%s)<br />", $name, $address, $phone);     //格式化結果輸出
    }
 
    $stmt->close();
    // 釋放mysqli_stmt對象占用的資源
}
 
$mysqli->close();
// 關閉與MySQL數據庫的連接
?>

輸出結果如下所示:

  1. D01部門的聯系人信息列表如下:
  2. 高某某 (海淀區,15801688338)
  3. 陳某某 (昌平區,15801682468)
  4. 白某某 (海淀區,15801689675)
  5. D02部門的聯系人信息列表如下:
  6. 洛某某 (朝陽區,15801681234)

在上面的示例中,根據提供的部門參數不同,從數據庫中分別取出兩個部門的聯系人信息。只要使用一次bind_result()方法綁定結果就可以了,並不需要每次執行都把查詢結果的各個數據列綁定到一些PHP變量上。

在生成網頁時,許多PHP腳本通常都會執行除參數以外,其他部分完全相同的查詢語句,針對這種重復執行一個查詢,每次迭代使用不同的參數情況,MySQL從4.1版本開始提供了一種名為預處理語句(prepared statement)的機制。它可以將整個命令向MySQL服務器發送一次,以后只有參數發生變化,MySQL服務器只需對命令的結構做一次分析就夠了。這不僅大大減少了需要傳輸的數據量,還提高了命令的處理效率。可以用mysqli擴展模式中提供的mysqli_stmt類的對象,去定義和執行參數化的SQL命令,mysqli_result類中包含的全部成員屬性和成員方法如表13-6和表13-7所示。

表13-6  mysqli_stmt類中的成員方法(共12個)

成員方法名

描    述

bind_param() 該方法把預處理語句各有關參數綁定到一些PHP變量上,注意參數的先后順序
bind_result() 預處理語句執行查詢之后,利用該方法將變量綁定到所獲取的字段
close() 一旦預處理語句使用結果之后,它所占用的資源可以通過該方法回收
data_seek() 在預處理語句中移動內部結果的指針
execute() 執行准備好的預處理語句
fetch() 獲取預處理語句結果的每條記錄,並將相應的字段賦給綁定結果
free_result() 回收由該對象指定的語句占用的內存
result_metadata() 從預處理中返回結果集原數據
prepare() 無論是綁定參數還是綁定結果,都需要使用該方法准備要執行的預處理語句
send_long_data() 發送數據塊
reset() 重新設置預處理語句
store_result() 從預處理語句中獲取結果集

 

 

 

 

 

 

 

 

 

 

 

 

 

表13-7  mysqli_stmt類中的成員屬性(共6個)

成員屬性名

描    述

$affected_rows 返回該對象指定的最后一條語句所影響的記錄數。注意,該方法只與插入、修改和刪除三種查詢句有關
$errno 返回該對象指定最近所執行語句的錯誤代碼
$error 返回該對象指定最近所執行語句的錯誤描述字符串
$param_count 返回給定的預處理語句中需要綁定的參數個數
$sqlstate 從先前的預處理語句中返回SQL狀態錯誤代碼
$num_rows 返回stmt對象指定的SELECT語句獲取的記錄數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM