php 调用未定义的方法 mysqli_stmt::get_result

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8321096/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 04:26:08  来源:igfitidea点击:

Call to undefined method mysqli_stmt::get_result

phpmysqli

提问by Kumar Kush

Here's my code:

这是我的代码:

include 'conn.php';
$conn = new Connection();
$query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?';
$stmt = $conn->mysqli->prepare($query);
$stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']);
$stmt->execute();
$result = $stmt->get_result();

I get the error on last line as: Call to undefined method mysqli_stmt::get_result()

我在最后一行收到错误:调用未定义的方法 mysqli_stmt::get_result()

Here is the code for conn.php:

这是 conn.php 的代码:

define('SERVER', 'localhost');
define('USER', 'root');
define('PASS', 'xxxx');
define('DB', 'xxxx');
class Connection{
    /**
     * @var Resource 
     */
    var $mysqli = null;

    function __construct(){
        try{
            if(!$this->mysqli){
                $this->mysqli = new MySQLi(SERVER, USER, PASS, DB);
                if(!$this->mysqli)
                    throw new Exception('Could not create connection using MySQLi', 'NO_CONNECTION');
            }
        }
        catch(Exception $ex){
            echo "ERROR: ".$e->getMessage();
        }
    }
}

If I write this line:

如果我写这一行:

if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';

It prints 'Statement NOT prepared'. If I run the query directly in the IDE replacing ? marks with values, it works fine. Please note that $conn object works fine in other queries in the project.

它打印'Statement NOT Prepared'。如果我直接在 IDE 中运行查询替换 ? 带有值的标记,它工作正常。请注意 $conn 对象在项目中的其他查询中工作正常。

Any help please.......

任何帮助请......

回答by bekay

Please read the user notes for this method:

请阅读此方法的用户注释:

http://php.net/manual/en/mysqli-stmt.get-result.php

http://php.net/manual/en/mysqli-stmt.get-result.php

It requires the mysqlnd driver... if it isn't installed on your webspace you will have to work with BIND_RESULT & FETCH!

它需要 mysqlnd 驱动程序...如果它没有安装在您的网站空间上,您将不得不使用 BIND_RESULT 和 FETCH!

https://secure.php.net/manual/en/mysqli-stmt.bind-result.php

https://secure.php.net/manual/en/mysqli-stmt.bind-result.php

https://secure.php.net/manual/en/mysqli-stmt.fetch.php

https://secure.php.net/manual/en/mysqli-stmt.fetch.php

回答by Bert Regelink

So if the MySQL Native Driver (mysqlnd) driver is not available, and therefore using bind_resultand fetchinstead of get_result, the code becomes:

因此,如果 MySQL Native Driver (mysqlnd) 驱动程序不可用,因此使用bind_resultfetch而不是get_result,代码变为:

include 'conn.php';
$conn = new Connection();
$query = 'SELECT EmailVerified, Blocked FROM users WHERE Email = ? AND SLA = ? AND `Password` = ?';
$stmt = $conn->mysqli->prepare($query);
$stmt->bind_param('sss', $_POST['EmailID'], $_POST['SLA'], $_POST['Password']);
$stmt->execute();
$stmt->bind_result($EmailVerified, $Blocked);
while ($stmt->fetch())
{
   /* Use $EmailVerified and $Blocked */
}
$stmt->close();
$conn->mysqli->close();

回答by M_R_K

Your system is missing the mysqlnd driver!

您的系统缺少 mysqlnd 驱动程序!

If you are able to install new packages on your (Debian/Ubuntu-based) server, install the driver:

如果您能够在(基于 Debian/Ubuntu 的)服务器上安装新软件包,请安装驱动程序:

sudo apt-get install php5-mysqlnd

and then restart your web server:

然后重新启动您的网络服务器:

sudo /etc/init.d/apache2 restart

回答by MasterKitano

for those searching for an alternative to $result = stmt->get_result() I've made this function which allows you to mimic the $result->fetch_assoc() but using directly the stmt object:

对于那些寻找 $result = stmt->get_result() 替代方法的人,我创建了这个函数,它允许您模拟 $result->fetch_assoc() 但直接使用 stmt 对象:

function fetchAssocStatement($stmt)
{
    if($stmt->num_rows>0)
    {
        $result = array();
        $md = $stmt->result_metadata();
        $params = array();
        while($field = $md->fetch_field()) {
            $params[] = &$result[$field->name];
        }
        call_user_func_array(array($stmt, 'bind_result'), $params);
        if($stmt->fetch())
            return $result;
    }

    return null;
}

as you can see it creates an array and fetches it with the row data, since it uses $stmt->fetch() internally, you can call it just as you would call mysqli_result::fetch_assoc (just be sure that the $stmt object is open and result is stored):

如您所见,它创建了一个数组并使用行数据获取它,因为它在内部使用 $stmt->fetch(),您可以像调用 mysqli_result::fetch_assoc 一样调用它(只需确保 $stmt 对象已打开并存储结果):

//mysqliConnection is your mysqli connection object
if($stmt = $mysqli_connection->prepare($query))
{
    $stmt->execute();
    $stmt->store_result();

    while($assoc_array = fetchAssocStatement($stmt))
    {
        //do your magic
    }

    $stmt->close();
}

hope this helps.

希望这可以帮助。

回答by IRSHAD

With PHP version 7.2 I just used nd_mysqliinstead of mysqliand it worked as expected.

在 PHP 7.2 版中,我只使用了nd_mysqli而不是mysqli,它按预期工作。

Steps to enable it into godaddy hosting server-

将其启用到 Godaddy 托管服务器的步骤-

  1. Login to cpanel.
  2. Click on "Select PHP version".
  3. As provided the snapshot of the latest configurations uncheck "mysqli"and enable "nd_mysqli".
  1. 登录到 cpanel。
  2. 单击“选择 PHP 版本”
  3. 提供最新配置的快照,取消选中“mysqli”并启用“nd_mysqli”

enter image description here

在此处输入图片说明

回答by Kirkland

I know this was already answered as to what the actual problem is, however I want to offer a simple workaround.

我知道这已经回答了实际问题是什么,但是我想提供一个简单的解决方法。

I wanted to use the get_results() method however I didn't have the driver, and I'm not somewhere I can get that added. So, before I called

我想使用 get_results() 方法,但是我没有驱动程序,而且我无法添加它。所以,在我打电话之前

$stmt->bind_results($var1,$var2,$var3,$var4...etc);

I created an empty array, and then just bound the results as keys in that array:

我创建了一个空数组,然后将结果绑定为该数组中的键:

$result = array();
$stmt->bind_results($result['var1'],$result['var2'],$result['var3'],$result['var4']...etc);

so that those results could easily be passed into methods or cast to an object for further use.

以便这些结果可以轻松地传递到方法中或转换为对象以供进一步使用。

Hope this helps anyone who's looking to do something similar.

希望这可以帮助任何想要做类似事情的人。

回答by ban-geoengineering

I was getting this same error on my server - PHP 7.0 with the mysqlndextension already enabled.

我在我的服务器上遇到了同样的错误 - PHP 7.0已经启用了mysqlnd扩展。

Solution was for me (thanks to this page) was to deselect the mysqliextension and select nd_mysqliinstead.

对我来说,解决方案(感谢此页面)是取消选择mysqli扩展并选择nd_mysqli

NB - You may be able to access the extensions selector in your cPanel. (I access mine via the Select PHP Versionoption.)

注意 - 您可以访问 cPanel 中的扩展选择器。(我通过选择 PHP 版本选项访问我的。)

回答by mti2935

I realize that it's been a while since there has been any new activity on this question. But, as other posters have commented - get_result()is now only available in PHP by installing the MySQL native driver (mysqlnd), and in some cases, it may not be possible or desirable to install mysqlnd. So, I thought it would be helpful to post this answer with info on how get the functionality that get_result()offers - without using get_result().

我意识到已经有一段时间没有关于这个问题的新活动了。但是,正如其他海报所评论的那样 -get_result()现在只能通过安装 MySQL 本机驱动程序 (mysqlnd) 在 PHP 中使用,并且在某些情况下,安装 mysqlnd 可能是不可能的或不可取的。因此,我认为发布此答案以及有关如何获取所get_result()提供功能的信息会有所帮助- 无需使用get_result().

get_result()is/was often combined with fetch_array()to loop through a result set and store the values from each row of the result set in a numerically-indexed or associative array. For example, the code below uses get_result() with fetch_array() to loop through a result set, storing the values from each row in the numerically-indexed $data[] array:

get_result()is/was 通常与fetch_array()循环结果集结合使用,并将结果集每一行的值存储在数字索引或关联数组中。例如,下面的代码使用 get_result() 和 fetch_array() 循环遍历结果集,将每一行的值存储在数字索引的 $data[] 数组中:

$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);                 
$stmt->bind_param('i', $c);                                             
$stmt->execute();
$result = $stmt->get_result();       
while($data = $result->fetch_array(MYSQLI_NUM)) {
   print $data[0] . ', ' . $data[1] . "<BR>\n"; 
}

However, if get_result()is not available (because mysqlnd is not installed), then this leads to the problem of how to store the values from each row of a result set in an array, without using get_result(). Or, how to migrate legacy code that uses get_result()to run without it (e.g. using bind_result()instead) - while impacting the rest of the code as little as possible.

但是,如果get_result()不可用(因为没有安装 mysqlnd),那么这会导致如何将结果集的每一行的值存储在数组中的问题,而不使用get_result(). 或者,如何迁移get_result()用于在没有它的情况下运行的遗留代码(例如,bind_result()改为使用) - 同时尽可能少地影响其余代码。

It turns out that storing the values from each row in a numerically-indexed array is not so straight-forward using bind_result(). bind_result()expects a list of scalar variables (not an array). So, it takes some doing to make it store the values from each row of the result set in an array.

事实证明,使用bind_result(). bind_result()需要一个标量变量列表(不是数组)。因此,需要做一些事情才能将结果集的每一行中的值存储在一个数组中。

Of course, the code could easily be modified as follows:

当然,代码可以很容易地修改如下:

$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);                 
$stmt->bind_param('i', $c);                                             
$stmt->execute();
$stmt->bind_result($data[0], $data[1]);
while ($stmt->fetch()) {
   print $data[0] . ', ' . $data[1] . "<BR>\n"; 
}

But, this requires us to explicitly list $data[0], $data[1], etc. individually in the call to bind_result(), which is not ideal. We want a solution that doesn't require us to have to explicitly list $data[0], $data[1], ... $data[N-1] (where N is the number of fields in the select statement) in the call to bind_results(). If we're migrating a legacy application that has a large number of queries, and each query may contain a different number of fields in the selectclause, the migration will be very labor intensive and prone to error if we use a solution like the one above.

但是,这要求我们在对 的调用中分别显式地列出 $data[0]、$data[1] 等bind_result(),这并不理想。我们想要一个不需要我们显式列出 $data[0], $data[1], ... $data[N-1] 的解决方案(其中 N 是 select 语句中的字段数)在调用bind_results(). 如果我们要迁移具有大量查询的遗留应用程序,并且每个查询可能在select子句中包含不同数量的字段,那么如果我们使用上述解决方案,迁移将非常费力且容易出错.

Ideally, we want a snippet of 'drop-in replacement' code - to replace just the line containing the get_result()function and the while() loop on the next line. The replacement code should have the same function as the code that it's replacing, without affecting any of the lines before, or any of the lines after - including the lines inside the while() loop. Ideally we want the replacement code to be as compact as possible, and we don't want to have to taylor the replacement code based on the number of fields in the selectclause of the query.

理想情况下,我们需要一段“插入式替换”代码——只替换包含get_result()函数的行和下一行的 while() 循环。替换代码应该与它正在替换的代码具有相同的功能,而不影响之前的任何行或之后的任何行 - 包括 while() 循环内的行。理想情况下,我们希望替换代码尽可能紧凑,并且我们不想根据select查询子句中的字段数量来调整替换代码。

Searching on the internet, I found a number of solutions that use bind_param()with call_user_func_array()(for example, Dynamically bind mysqli_stmt parameters and then bind result (PHP)), but most solutions that I found eventually lead to the results being stored in an associative array, not a numerically-indexed array, and many of these solutions were not as compact as I would like and/or were not suited as 'drop-in replacements'. However, from the examples that I found, I was able to cobble together this solution, which fits the bill:

在互联网上搜索,我发现了许多使用bind_param()with的解决方案call_user_func_array()(例如,动态绑定 mysqli_stmt 参数,然后绑定结果 (PHP)),但我发现的大多数解决方案最终都会导致结果存储在关联数组中,而不是一个数字索引的数组,其中许多解决方案并不像我想要的那么紧凑和/或不适合作为“插入式替换”。然而,从我发现的例子中,我能够拼凑出这个符合要求的解决方案:

$c=1000;
$sql="select account_id, username from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);                 
$stmt->bind_param('i', $c);                                             
$stmt->execute();
$data=array();
for ($i=0;$i<$mysqli->field_count;$i++) { 
    $var = $i;
    $$var = null; 
    $data[$var] = &$$var; 
}
call_user_func_array(array($stmt,'bind_result'), $data);
while ($stmt->fetch()) {
   print $data[0] . ', ' . $data[1] . "<BR>\n"; 
}

Of course, the for() loop can be collapsed into one line to make it more compact.

当然,for() 循环可以折叠成一行以使其更紧凑。

I hope this helps anyone who is looking for a solution using bind_result()to store the values from each row in a numerically-indexed array and/or looking for a way to migrate legacy code using get_result(). Comments welcome.

我希望这可以帮助任何正在寻找用于将bind_result()每一行的值存储在数字索引数组中的解决方案和/或寻找一种使用get_result(). 欢迎评论。

回答by ch271828n

Here is my alternative. It is object-orientedand is more like mysql/mysqli things.

这是我的选择。它是面向对象的,更像是 mysql/mysqli 的东西。

class MMySqliStmt{
    private $stmt;
    private $row;

    public function __construct($stmt){
        $this->stmt = $stmt;
        $md = $stmt->result_metadata();
        $params = array();
        while($field = $md->fetch_field()) {
            $params[] = &$this->row[$field->name];
        }
        call_user_func_array(array($stmt, 'bind_result'), $params) or die('Sql Error');
    }

    public function fetch_array(){
        if($this->stmt->fetch()){
            $result = array();
            foreach($this->row as $k => $v){
                $result[$k] = $v;
            }
            return $result;
        }else{
            return false;
        }
    }

    public function free(){
        $this->stmt->close();
    }
}

Usage:

用法:

$stmt = $conn->prepare($str);
//...bind_param... and so on
if(!$stmt->execute())die('Mysql Query(Execute) Error : '.$str);
$result = new MMySqliStmt($stmt);
while($row = $result->fetch_array()){
    array_push($arr, $row);
    //for example, use $row['id']
}
$result->free();
//for example, use the $arr

回答by Stefan S.

I have written two simple functions that give the same functionality as $stmt->get_result();, but they don't require the mysqlnd driver.

我编写了两个与 具有相同功能的简单函数$stmt->get_result();,但它们不需要 mysqlnd 驱动程序。

You simply replace

你只需更换

$result = $stmt->get_result();with$fields = bindAll($stmt);

$result = $stmt->get_result();$fields = bindAll($stmt);

and

$row= $stmt->get_result();with$row = fetchRowAssoc($stmt, $fields);.

$row= $stmt->get_result();$row = fetchRowAssoc($stmt, $fields);.

(To get the numbers of returned rows you can use $stmt->num_rows.)

(要获取返回的行数,您可以使用$stmt->num_rows。)

You just have to place these two functionsI have written somewhere in your PHP Script. (for example right at the bottom)

您只需我编写的这两个函数放在您的 PHP 脚本中。(例如在底部)

function bindAll($stmt) {
    $meta = $stmt->result_metadata();
    $fields = array();
    $fieldRefs = array();
    while ($field = $meta->fetch_field())
    {
        $fields[$field->name] = "";
        $fieldRefs[] = &$fields[$field->name];
    }

    call_user_func_array(array($stmt, 'bind_result'), $fieldRefs);
    $stmt->store_result();
    //var_dump($fields);
    return $fields;
}

function fetchRowAssoc($stmt, &$fields) {
    if ($stmt->fetch()) {
        return $fields;
    }
    return false;
}

How it works:

它是如何工作的

My code uses the $stmt->result_metadata();function to figure out how many and which fields are returned and then automatically binds the fetched results to pre-created references. Works like a charm!

我的代码使用该$stmt->result_metadata();函数来确定返回了多少字段和哪些字段,然后自动将获取的结果绑定到预先创建的引用。奇迹般有效!