最近我偶然发现一个曾经工作得很好的lib中的错误,如果我能弄清楚它在哪里,我会被诅咒。
代码示例如下,我为其中的调试内容道歉,但我正试图让它工作。
问题是$ temp是一个具有正确键(列名)的数组,但所有值都是NULL。
我认为问题在于
call_user_func_array(array($query, 'bind_result'), $params);
位,但不能真正地绕过它。
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;
}
答案 0 :(得分:3)
您提供的代码适合我。
call_user_func_array(...)
函数只调用具有给定数组的bindParam
对象上的bind_result
或$query
方法,就好像您已将数组的每个元素都提供为方法论证。
您可能需要使用以下代码检查出现问题的SQL语句。我已经重写了一下,以使其完全可测试,因为原始代码依赖于抽象层中的语句类。
<?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;
}
答案 1 :(得分:2)
如果我们可以在开始时选择服务器,我们可以使用php-mysqlnd模块而不是php-mysql模块用于PHP。 (或者你们中的一些人可能已经在使用它,运行&#34; phpinfo();&#34;并搜索&#34; mysqlnd&#34;):
public function fetchRows(){
...
$query->execute();
$res = $query->get_result();
while (($row = $res->fetch_assoc()))
$result[] = $row;
return $result;
}
}
这对我来说似乎更简单。