Mysqli抽象,从准备好的语句中获取数组 [英] Mysqli abstraction, fetching arrays from prepared statements
问题描述
最近,我偶然发现了以前正常工作的lib中的一个错误,如果我弄清楚它在哪里,我该死的.
Lately I've stumbled upon an error in a lib that used to work just fine, and I'll be damned if I can figure out where it is.
下面是代码示例,对于其中的调试内容,我深表歉意,但我正在尝试使其正常工作.
The code sample is below, and I apologize for the debug stuff that's inside it, but I'm trying to get it to work.
问题在于$ temp是具有正确键(列名)的数组,但是所有值均为NULL.
The problem is that $temp is an array with correct key (the name of the columns) but all the values are NULL.
我认为问题出在
call_user_func_array(array($query, 'bind_result'), $params);
有点,但不能真正把我的头缠住它.
bit, but can't really wrap my head around it.
public function fetchRows(){
error_reporting(E_ALL+E_NOTICE);
$args = func_get_args();
$sql = array_shift($args);
traceVar($sql, "Query");
$colTypes = array_shift($args);
if (!$query = $this->prepare($sql, $colTypes)) {
die('Please check your sql statement : unable to prepare');
}
if (count($args)){
traceVar($args,'Binding params with');
call_user_func_array(array($query,'bindParam'), $args);
}
$query->execute();
$meta = $query->result_metadata();
while ($field = $meta->fetch_field()) {
$params[] = &$row[$field->name];
}
traceVar($params,'Binding results with');
call_user_func_array(array($query, 'bind_result'), $params);
while ($query->fetch()) {
traceVar($row,'After fetch');
$temp = array();
foreach($row as $key => $val) {
$temp[$key] = $val;
}
$result[] = $temp;
}
$meta->free();
$query->close();
//self::close_db_conn();
return $result;
}
推荐答案
您提供的代码对我有用.
The code you provided works for me.
call_user_func_array(...)
函数只需使用给定的数组调用$query
对象上的bindParam
或bind_result
方法,就好像您已将数组的每个元素提供为方法参数一样.
The call_user_func_array(...)
function just calls the bindParam
or bind_result
methods on the $query
object with the given array, as if you had provided each element of the array as a method argument.
您可能想用下面的代码检查遇到问题的SQL语句.为了使它完全可测试,我做了一些重写,因为原始代码取决于抽象层中的语句类.
You may want to check the SQL statement you are having the problem with, with the code below. I've rewritten it a bit in order to make it fully testable, since the original code depends on the statement class in your abstraction layer.
<?php
$db_host = 'localhost';
$db_user = 'username';
$db_pass = 'password';
$db_name = 'database';
$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name);
print_r(fetchRows('SELECT something from some_table WHERE some_id = ?', 'i', 1));
function traceVar($a, $b) {
print_r(array($b => $a));
}
function fetchRows(){
error_reporting(E_ALL+E_NOTICE);
$args = func_get_args();
$sql = array_shift($args);
traceVar($sql, "Query");
// Keep the column types for bind_param.
// $colTypes = array_shift($args);
// Column types were originally passed here as a second
// argument, and stored in the statement object, I suppose.
if (!$query = $GLOBALS['mysqli']->prepare($sql)){ //, $colTypes)) {
die('Please check your sql statement : unable to prepare');
}
if (count($args)){
traceVar($args,'Binding params with');
// Just a quick hack to pass references in order to
// avoid errors.
foreach ($args as &$v) {
$v = &$v;
}
// Replace the bindParam function of the original
// abstraction layer.
call_user_func_array(array($query,'bind_param'), $args); //'bindParam'), $args);
}
$query->execute();
$meta = $query->result_metadata();
while ($field = $meta->fetch_field()) {
$params[] = &$row[$field->name];
}
traceVar($params,'Binding results with');
call_user_func_array(array($query, 'bind_result'), $params);
while ($query->fetch()) {
traceVar($row,'After fetch');
$temp = array();
foreach($row as $key => $val) {
$temp[$key] = $val;
}
$result[] = $temp;
}
$meta->free();
$query->close();
//self::close_db_conn();
return $result;
}
这篇关于Mysqli抽象,从准备好的语句中获取数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!