2009-12-29 63 views
8

我看到使用mysqli_fetch_object的所有示例使用mysql_query(),我無法使它與預處理語句一起使用。有人知道這段代碼有什麼問題,因爲fetch_object返回null。是否可以使用mysqli_fetch_object和預處理語句

$sql = "select 1 from dual"; 
printf("preparing %s\n", $sql); 
$stmt = $link->prepare($sql); 
printf("prepare statement %s\n", is_null($stmt) ? "is null" : "created"); 
$rc = $stmt->execute(); 
printf("num rows is %d\n", $stmt->num_rows); 
$result = $stmt->result_metadata(); 
printf("result_metadata %s\n", is_null($result) ? "is null" : "exists"); 
$rc = $result->fetch_object(); 
printf("fetch object returns %s\n", is_null($rc) ? "NULL" : $rc); 
$stmt->close(); 

輸出是:

preparing select 1 from dual 
prepare statement created 
num rows is 0 
result_metadata exists 
fetch object returns NULL 
+0

當然NUM行應> 0,如果你期待一個非空對象返回? – jcuenod 2009-12-29 19:38:43

回答

0

我不相信的接口工作那樣。

通過文檔和示例(http://www.php.net/manual/en/mysqli.prepare.php),似乎$ stmt-> execute()不會返回結果集,而是一個指示成功/失敗的布爾值(http://www.php.net/manual/en/mysqli-stmt.execute.php)。要實際得到結果,需要使用$ stmt-> bind_result(http://www.php.net/manual/en/mysqli-stmt.bind-result.php)將變量綁定到結果集(在執行調用之後)。

完成所有這些之後,可以重複調用$ stmt-> fetch()()來使用當前行的列值填充綁定變量。我沒有看到任何關於$ stmt-> fetch_object()的提及,也沒有看到該接口如何與所描述的變量綁定方案一起工作。

所以這是從mysqli準備的陳述「正常」結果取回的故事。

在你的代碼中,有些東西我懷疑是錯誤,或者至少我不確定你是否打算這樣做。 您行:

$result = $stmt->result_metadata(); 

assignes結果集的元數據,且其本身表現爲一個結果,到$ result變量。根據文檔(http://www.php.net/manual/en/mysqli-stmt.result-metadata.php),您只能在這些「特殊」種類的結果集中使用這些方法的子集,而fetch_object()不是其中的一個(至少未明確列出)。

也許這是一個bug,fetch_object()沒有實現這些元數據結果集,也許你應該在bugs.mysql.com上提交一個bug。

+0

我想使用fetch_object,所以我不必定義一個類並顯式綁定成員變量。我將嘗試爲準備好的語句創建我自己的fetch_object。 – BeWarned 2009-12-29 20:21:47

11

這是我用來從預備語句創建對象的代碼。
它也許可以用在mysqli的子類中?

$query = "SELECT * FROM category WHERE id = ?"; 
    $stmt = $this->_db->prepare($query); 

    $value = 1; 
    $stmt->bind_param("i", $value); 

    $stmt->execute(); 

    // bind results to named array 
    $meta = $stmt->result_metadata(); 
    $fields = $meta->fetch_fields(); 
    foreach($fields as $field) { 
     $result[$field->name] = ""; 
     $resultArray[$field->name] = &$result[$field->name]; 
    } 

    call_user_func_array(array($stmt, 'bind_result'), $resultArray); 

    // create object of results and array of objects 
    while($stmt->fetch()) { 
     $resultObject = new stdClass(); 

     foreach ($resultArray as $key => $value) { 
      $resultObject->$key = $value; 
     } 

     $rows[] = $resultObject; 
    } 

    $stmt->close(); 
+0

謝謝,我結束了一些事情,就像你的代碼 – BeWarned 2010-02-12 09:26:49

7

MySQL的本機驅動程序的擴展名(mysqlnd),有get_result方法:

$stmt->execute(); 
$obj = $stmt->get_result()->fetch_object(); 
+1

這是一個很好的解決方案;您可以使用'$ obj-> db_field_name;'等檢索結果OO風格,正是我所期待的,謝謝。 – Timmy 2014-12-30 14:10:18

+2

警告:這隻適用於如果您使用'mysqlnd'驅動程序 – Populus 2015-11-24 23:47:09

+0

@Populus謝謝,在答案正文中添加。 – T30 2016-12-20 10:02:23