2009-12-29 33 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