这是我的代码:
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();
Run Code Online (Sandbox Code Playgroud)
我在最后一行得到错误:调用未定义的方法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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我写这行:
if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';
Run Code Online (Sandbox Code Playgroud)
它打印'Statement NOT prepared'.如果我直接在IDE中运行查询替换?用值标记,它工作正常.请注意,$ conn对象在项目中的其他查询中正常工作.
请帮忙.......
bek*_*kay 142
请阅读此方法的用户说明:
http://php.net/manual/en/mysqli-stmt.get-result.php
它需要mysqlnd驱动程序......如果它没有安装在你的网站空间上,你将不得不使用BIND_RESULT和FETCH!
https://secure.php.net/manual/en/mysqli-stmt.bind-result.php
https://secure.php.net/manual/en/mysqli-stmt.fetch.php
Ber*_*ink 48
因此,如果MySQL本机驱动程序(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();
Run Code Online (Sandbox Code Playgroud)
M_R*_*R_K 43
你的系统缺少mysqlnd驱动程序!
如果您能够在(基于Debian/Ubuntu的)服务器上安装新软件包,请安装驱动程序:
sudo apt-get install php5-mysqlnd
Run Code Online (Sandbox Code Playgroud)
然后重新启动您的Web服务器:
sudo /etc/init.d/apache2 restart
Run Code Online (Sandbox Code Playgroud)
Mas*_*ano 37
对于那些搜索$ 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;
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到它创建一个数组并使用行数据获取它,因为它在内部使用$ 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();
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
Kir*_*and 10
我知道这已经回答了实际问题是什么,但是我想提供一个简单的解决方法.
我想使用get_results()方法,但是我没有驱动程序,而且我不在某个地方,我可以添加它.所以,在我打电话之前
$stmt->bind_results($var1,$var2,$var3,$var4...etc);
Run Code Online (Sandbox Code Playgroud)
我创建了一个空数组,然后将结果绑定为该数组中的键:
$result = array();
$stmt->bind_results($result['var1'],$result['var2'],$result['var3'],$result['var4']...etc);
Run Code Online (Sandbox Code Playgroud)
这样可以很容易地将这些结果传递给方法或转换为对象以供进一步使用.
希望这有助于任何想要做类似事情的人.
IRS*_*HAD 10
在PHP 7.2版中,我只使用nd_mysqli而不是mysqli,它可以按预期工作。
将其启用到godaddy托管服务器中的步骤-
我意识到已经有一段时间了,因为在这个问题上有任何新的活动.但是,正如其他海报所评论的那样 - get_result()现在只能通过安装MySQL本机驱动程序(mysqlnd)在PHP中使用,在某些情况下,安装mysqlnd可能是不可能或不可取的.所以,我认为发布这个答案以及如何获得所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";
}
Run Code Online (Sandbox Code Playgroud)
但是,如果get_result()不可用(因为未安装mysqlnd),则会导致如何在数组中存储结果集的每一行中的值而不使用的问题get_result().或者,如何迁移get_result()用于在没有它的情况下运行的遗留代码(例如使用bind_result()) - 同时尽可能少地影响其余代码.
事实证明,在数字索引数组中存储每行的值并不是那么直接使用bind_result(). 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";
}
Run Code Online (Sandbox Code Playgroud)
但是,这要求我们在调用中单独明确地列出$ data [0],$ data [1]等bind_result(),这是不理想的.我们想要一个不需要我们必须明确列出$ data [0],$ data [1],... $ data [N-1](其中N是select语句中的字段数)的解决方案在打电话给bind_results().如果我们正在迁移具有大量查询的遗留应用程序,并且每个查询可能在select子句中包含不同数量的字段,那么迁移将非常耗费人力并且如果我们使用如上所述的解决方案则容易出错.
理想情况下,我们需要一个"直接替换"代码片段 - 仅替换包含get_result()函数的行和下一行的while()循环.替换代码应该具有与它替换的代码相同的功能,而不会影响之前的任何行,或者之后的任何行 - 包括while()循环内的行.理想情况下,我们希望替换代码尽可能紧凑,并且我们不希望根据select查询子句中的字段数来替换替换代码.
在互联网上搜索,我发现了一些使用的解决方案bind_param()与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";
}
Run Code Online (Sandbox Code Playgroud)
当然,for()循环可以折叠成一行,使其更紧凑.
我希望这有助于任何正在寻找解决方案的人使用bind_result()存储数字索引数组中每行的值和/或寻找使用迁移旧代码的方法get_result().欢迎评论.
这是我的替代方案.它是面向对象的,更像是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();
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
$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
Run Code Online (Sandbox Code Playgroud)