调用未定义的方法mysqli_stmt :: 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(); $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中运行查询replace? 用值标记,它工作正常。 请注意$ conn对象在项目的其他查询中工作正常。
任何帮助请…….
请阅读此方法的用户注意事项:
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
所以如果MySQL Native Driver(mysqlnd)驱动程序不可用,并且因此使用bind_result和fetch取代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();
你的系统缺lessmysqlnd驱动!
如果您可以在(基于Debian / Ubuntu的)服务器上安装新软件包,请安装驱动程序:
sudo apt-get install php5-mysqlnd
然后重新启动您的Web服务器:
sudo /etc/init.d/apache2 restart
对于那些寻找替代$ 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; }
你可以看到它创build了一个数组并获取行数据,因为它在内部使用$ 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(); }
希望这可以帮助。
我知道这已经回答了什么是实际问题,但是我想提供一个简单的解决方法。
我想使用get_results()方法,但是我没有驱动程序,而且我不是可以添加的地方。 所以,我打电话之前
$stmt->bind_results($var1,$var2,$var3,$var4...etc);
我创build了一个空数组,然后将结果作为该数组中的键绑定:
$result = array(); $stmt->bind_results($result['var1'],$result['var2'],$result['var3'],$result['var4']...etc);
以便这些结果可以很容易地传递到方法或投射到一个对象进一步使用。
希望这可以帮助任何想要做类似事情的人。
这是我的select。 它是面向对象的 ,更像是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()
提供的function相关的信息get_result()
,而不使用get_result()
。
get_result()
通常与fetch_array()
结合来遍历结果集,并将结果集中每行的值存储在数字索引或关联数组中。 例如,下面的代码使用带有fetch_array()的get_result()循环遍历一个结果集,并将每行的值存储在数字索引的$ 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"; }
但是,如果get_result()
不可用(因为没有安装mysqlnd),则会导致如何将结果集的每一行中的值存储到数组中,而不使用get_result()
。 或者,如何在不使用get_result()
情况下迁移遗留代码(例如,使用bind_result()
),而尽可能less地影响代码的其余部分。
事实certificate,使用bind_result()
将每行中的值存储在数字索引数组中并不那么简单。 bind_result()
需要一个标量variables列表(不是数组)。 所以,需要做一些工作来使结果集中每一行的值存储在一个数组中。
当然,代码可以很容易地修改如下:
$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"; }
但是,这要求我们在调用bind_result()
单独显式地列出$ data [0],$ data [1]等,这是不理想的。 我们想要一个解决scheme,不需要我们必须显式地列出$ data [0],$ data [1],… $ data [N-1](其中N是select语句中的字段数)在调用bind_results()
。 如果我们正在迁移具有大量查询的遗留应用程序,并且每个查询在select
子句中可能包含不同数量的字段,那么迁移将非常耗费人力,并且如果使用类似于以上。
理想情况下,我们需要一个“drop-in replacement”代码片段来代替包含get_result()
函数和下一行的while()循环的行。 replace代码应该与它所replace的代码具有相同的function,而不会影响之前的任何行,或者之后的任何行 – 包括while()循环中的行。 理想情况下,我们希望replace代码尽可能紧凑,而且我们不希望根据查询的select
子句中的字段数来更新代码。
在互联网上search,我发现了一些使用bind_param()
和call_user_func_array()
的解决scheme(例如, dynamic绑定mysqli_stmt参数,然后绑定结果(PHP) ),但是我发现大多数解决scheme最终导致存储结果在一个关联数组中,不是一个数字索引的数组,而且这些解决scheme中的很多并不像我想要的那样紧凑和/或不适合作为“直接replace”。 然而,从我发现的例子中,我能够凑齐这个符合法案的解决scheme:
$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()循环可以折叠成一行,使其更加紧凑。
我希望这有助于任何正在寻找解决scheme的人使用bind_result()
将每行的值存储在数字索引数组中,和/或寻找使用get_result()
来迁移遗留代码的方法。 评论欢迎。