Py学习  »  DATABASE

php mysqli_stmt::未定义get_result[重复]

Nervo Tan • 4 年前 • 988 次点击  

这是我的代码:

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_stmt::get_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 object在项目中的其他查询中工作正常。

请帮忙……

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/39898
 
988 次点击  
文章 [ 10 ]  |  最新文章 4 年前
Stefan S.
Reply   •   1 楼
Stefan S.    6 年前

我已经编写了两个简单的函数,它们提供了与 $stmt->get_result(); ,但它们不需要mysqlnd驱动程序。

你只是 代替

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

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

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

你只需要 放置这两个函数 我已经写了 在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;
}

工作原理 :

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

fzyzcjy
Reply   •   2 楼
fzyzcjy    8 年前

这是我的选择。它是 面向对象 更像是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
IRSHAD
Reply   •   3 楼
IRSHAD    5 年前

在php 7.2版本中,我刚刚使用 Nd_mysqli公司 而不是 米斯利 一切如期而至。

启用godaddy托管服务器的步骤-

  1. 登录到cpanel。
  2. 点击 “选择php版本” .
  3. 如果提供了最新配置的快照,请取消选中 “mysqli” 使能 “nd_mysqli” .

enter image description here

ban-geoengineering
Reply   •   4 楼
ban-geoengineering    5 年前

我的服务器上也出现了同样的错误-php 7.0 mysqlnd公司 扩展已启用。

解决办法是给我的(多亏了 this page )是取消选择 米斯利 扩展和选择 Nd_mysqli公司 相反。

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

Community Peter Hart
Reply   •   5 楼
Community Peter Hart    6 年前

我意识到这个问题已经有一段时间没有新的活动了。但是,正如其他海报评论的那样- get_result() 现在只有通过安装mysql本地驱动程序(mysqlnd)才能在php中使用,在某些情况下,安装mysqlnd可能是不可能或不可取的。所以,我认为将这个答案与如何获得 获取结果() 提供-不使用 获取结果()

获取结果() 常与 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"; 
}

但是,如果 获取结果() 不可用(因为未安装mysqlnd),那么这将导致一个问题,即如何在不使用 获取结果() . 或者,如何迁移使用 获取结果() 在没有它的情况下运行(例如使用 bind_result() 相反)-同时尽可能少地影响其余代码。

事实证明,在数字索引数组中存储每一行的值并不是那么直接地使用 绑定结果() 绑定结果() 需要标量变量列表(不是数组)。因此,要使它将结果集的每一行的值存储在数组中,需要做一些工作。

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

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

但是,这要求我们在调用 绑定结果() ,这并不理想。我们想要一个不需要显式列出$data[0],$data[1],…$data[n-1](其中n是select语句中的字段数) bind_results() . 如果迁移的是具有大量查询的遗留应用程序,并且每个查询在 select 子句,如果使用上述解决方案,则迁移将是非常劳动密集型的,并且容易出错。

理想情况下,我们需要一段“drop-in-replacement”代码-仅替换包含 获取结果() 函数和下一行的while()循环。替换代码应该具有与其替换的代码相同的函数,而不影响之前的任何行或之后的任何行—包括while()循环中的行。理想情况下,我们希望替换代码尽可能紧凑,并且不希望基于 选择 查询的子句。

在互联网上搜索,我发现了许多解决方案 bind_param() 具有 call_user_func_array() (例如, Dynamically bind mysqli_stmt parameters and then bind result (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"; 
}

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

我希望这能帮助那些正在寻找解决方案的人 绑定结果() 将每行中的值存储在数字索引数组中和/或使用 获取结果() . 欢迎评论。

Kirkland
Reply   •   6 楼
Kirkland    10 年前

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

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

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

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

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

这样,这些结果就可以很容易地传递到方法中或转换为对象以供进一步使用。

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

Ĭsααc tիε βöss MasterKit
Reply   •   7 楼
Ĭsααc tիε βöss MasterKit    6 年前

对于那些寻找$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_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();
}

希望这有帮助。

Cody Gray
Reply   •   8 楼
Cody Gray    6 年前

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

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

sudo apt-get install php5-mysqlnd

然后重新启动Web服务器:

sudo /etc/init.d/apache2 restart
Bert Regelink
Reply   •   9 楼
Bert Regelink    6 年前

因此,如果mysql本机驱动程序(mysqlnd)不可用,则使用 绑定结果 取来 而不是 获取结果 ,代码变为:

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();
Matt Gibson bekay
Reply   •   10 楼
Matt Gibson bekay    8 年前

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

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

它需要mysqlnd驱动程序…如果它没有安装在您的web空间上,您将不得不使用bind_result&fetch!

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

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