私信  •  关注

Community Peter Hart

Community Peter Hart 最近创建的主题
Community Peter Hart 最近回复了
6 年前
回复了 Community Peter Hart 创建的主题 » php mysqli_stmt::未定义get_result[重复]

我意识到这个问题已经有一段时间没有新的活动了。但是,正如其他海报评论的那样- 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()循环可以折叠成一行,使其更紧凑。

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