Php Mysqli抽象,从准备好的语句中获取数组
最近,我在一个lib中偶然发现了一个错误,这个lib过去工作得很好,如果我能找出它在哪里,我会被诅咒的 下面是代码示例,对于其中的调试内容,我深表歉意,但我正在努力让它正常工作 问题是$temp是一个具有正确键(列名称)的数组,但所有值都为NULL 我认为问题在于Php Mysqli抽象,从准备好的语句中获取数组,php,mysqli,abstraction,Php,Mysqli,Abstraction,最近,我在一个lib中偶然发现了一个错误,这个lib过去工作得很好,如果我能找出它在哪里,我会被诅咒的 下面是代码示例,对于其中的调试内容,我深表歉意,但我正在努力让它正常工作 问题是$temp是一个具有正确键(列名称)的数组,但所有值都为NULL 我认为问题在于 call_user_func_array(array($query, 'bind_result'), $params); 有一点,但我真的不知道该怎么办 public function fetchRows(){ error_
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;
}
你提供的代码对我有用 该函数只调用具有给定数组的
$query
对象上的bindParam
或bind_result
方法,就好像您已将数组的每个元素作为方法参数提供一样
您可能需要使用下面的代码检查您遇到问题的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;
}
如果我们可以在开始时选择服务器,那么我们可以使用php mysqlnd模块而不是php的php mysql模块。(或者有些人可能已经在使用它,请运行“phpinfo();”并搜索“mysqlnd”):
这对我来说似乎更简单。我试过了,效果很好,我想知道我的原始代码在哪里被破坏了。在实现您的更改时,我一定犯了一些错误,如果我将函数重写为,然后运行,我仍然会得到“Array([0]=>Array([ID]=>[Username]=>[Password]=>[Name]=>[Email]=>[AccessLevel]=>[IsTemp]=>)“如果它有用的话,我还把这个类中的其他部分放在了这里,问题似乎出在我在上一篇评论中发布的其他方法上。我放置了一个$db=$this->connection;在if(!$query=$db->prepare($sql)){(因此使用的是原始对象而不是包装器类)并且它可以工作之前。有没有关于我可能做错了什么的线索?查看您提供的其他代码,我注意到DBStatement::prepare(…)
为空,这将解释为什么需要$db=$this->connection;
才能使其工作:-)。您可以检查DBStatement::prepare(…)
您的原始代码中的方法也是空的?我可以问一下,使用这些新知识,您将回答多少问题?粗略估计是可以的。只是因为在过去,我搜索了其中一些解决方案,没有注意到有一个get\u result()这可能也有用。所以添加它以供未来用户参考。两个是一个相当大的数量。尽管你将回答所有关于这个问题的数千个问题
public function fetchRows(){
...
$query->execute();
$res = $query->get_result();
while (($row = $res->fetch_assoc()))
$result[] = $row;
return $result;
}
}