Php 调用未定义的方法mysqli\u stmt::get\u result

Php 调用未定义的方法mysqli\u stmt::get\u result,php,mysqli,Php,Mysqli,这是我的密码: 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'], $_P

这是我的密码:

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();
最后一行的错误是:调用未定义的方法mysqli\u stmt::get\u result()

以下是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(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';
它打印“未准备的声明”。如果我直接在IDE中运行查询?用值标记,效果很好。请注意,$conn对象在项目中的其他查询中工作正常


任何帮助请……

请阅读此方法的用户说明:

它需要mysqlnd驱动程序。。。如果它没有安装在您的Web空间上,您将不得不使用BIND_RESULT&FETCH


因此,如果MySQL本机驱动程序(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();

您的系统缺少mysqlnd驱动程序

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

sudo apt get安装php5 mysqlnd
然后重新启动web服务器:

sudo/etc/init.d/apache2重新启动

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

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

$stmt->bind_results($var1,$var2,$var3,$var4...etc);
我创建了一个空数组,然后将结果绑定为该数组中的键:

$result = array();
$stmt->bind_results($result['var1'],$result['var2'],$result['var3'],$result['var4']...etc);
因此,这些结果可以很容易地传递到方法或转换到对象以供进一步使用


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

对于那些正在搜索替代
$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;
}
正如您所看到的,它创建了一个数组并使用行数据获取它,因为它在内部使用
$stmt->fetch()
,您可以像调用
mysqli\u result::fetch\u assoc
一样调用它(只需确保
$stmt
对象已打开并存储了结果):


这是我的选择。它是面向对象的,更像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();
    }
}
用法:

$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

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

get\u result()
通常与
fetch\u 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"; 
}
但是,这要求我们在调用
bind_result()
时分别显式列出$data[0]、$data[1]等,这并不理想。我们需要的解决方案不需要显式列出$data[0]、$data[1]、$调用
bind\u results()
中的数据[N-1](其中N是select语句中的字段数)。如果我们正在迁移一个具有大量查询的遗留应用程序,并且每个查询在
select
子句中可能包含不同数量的字段,那么如果我们使用类似于上面的解决方案,迁移将非常费力,并且容易出错

理想情况下,我们需要一段“drop-in-replacement”代码——只替换包含
get\u result()
函数的行和下一行的while()循环。替换代码应具有与其替换的代码相同的功能,而不影响之前或之后的任何行,包括while()循环中的行。理想情况下,我们希望替换代码尽可能紧凑,并且我们不希望必须根据查询的
select
子句中的字段数对替换代码进行泰勒运算

在互联网上搜索,我发现了许多使用
bind\u param()
call\u user\u func\u array()的解决方案。
(例如,),但我发现的大多数解决方案最终导致结果存储在关联数组中,而不是数字索引数组中,并且这些解决方案中的许多都没有我希望的那么紧凑和/或不适合作为“插入式替换”。然而,从我发现的示例中,我能够拼凑出符合要求的解决方案:

$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"; 
}
$c=1000;

$sql=“select account\u id,username from account\u id我已经编写了两个简单的函数,它们提供了与
$stmt->get\u result();
相同的功能,但它们不需要mysqlnd驱动程序

您只需替换

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

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

(要获取返回的行数,可以使用
$stmt->num\u rows

您只需将这两个函数放置在PHP脚本中的某个地方(例如,在底部)

工作原理:

我的代码使用
$stmt->result_metadata();
函数计算返回的字段数和字段数,然后自动将获取的结果绑定到预先创建的引用。效果非常好$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"; }
$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"; 
}
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;
}
// Get column names 
$sql = 'SHOW COLUMNS FROM users';
$get_coulmns = $mysqli->query($sql);

while($row = $get_coulmns->fetch_assoc()){
    $columns[] = $row['Field'];
}

// Assign references
$variables = array();
for ($i = 0; $i < count($columns); $i++) {
    $variables[] = &${$columns[$i]};
}
 
/*
  Other code here
*/

// Unpack variable references
$stmt->bind_result(...$variables);
echo $id, PHP_EOL;
echo $username, PHP_EOL;
echo $password, PHP_EOL;

... etc