我试图为mysqli连接编写一个非常小的抽象层,但遇到了一个问题。由于我维护的是旧代码,所以我需要从我的查询中获得一个关联数组,因为这是设置代码的方式,因此一旦工作正常,我的工作就会减少……此函数适用于各种查询(不仅仅是select).
我写的函数是:
function connectDB($query,$v=array()) {
$mysqli = new mysqli(HOST,USER,PW,DATABASE);
if($res=$mysqli->prepare($query)) {
//dynamically bind all $v
if($v) {
$values=array($v[0]);
for($i=1; $i<count($v); $i++) {
${'bind'.$i}=$v[$i];
$values[]=&${'bind'.$i};
}
call_user_func_array(array($res,'bind_param'),$values);
}
$res->execute();
//bind all table rows to result
if(strtolower(substr($query,0,6))=="select") {
$fields=array();
$meta=$res->result_metadata();
while($field=$meta->fetch_field()) {
${$field->name}=null;
$fields[$field->name]=&${$field->name};
}
call_user_func_array(array($res,"bind_result"),$fields);
//return associative array
$results = array();
$i=0;
while($res->fetch()) {
$results[$i]=array();
foreach($fields as $k => $v) $results[$i][$k] = $v;
$i++;
}
}
else {
$results=$mysqli->affected_rows;
if($mysqli->affected_rows<1) $results=$mysqli->info;
}
$res->close();
}
$mysqli->close();
return $results;
}所以如果我打电话:
$MySqlres=connectDB("select * from `modx_events` events limit 1");
var_dump($MySqlres);我得到一个很好的关联数组与我的选择的内容。
不幸的是,下面的mysql查询将返回NULL作为其所有数组键的值:
$MySqlres=connectDB("select *, events.`id` as `ID`,venues.`name` as `venueName`,
venues.`suburb` as `venueSuburb`,venues.`advertiser` as `venueAdvertiser`
from `modx_events` events left join `modx_venues` venues on events.`venue`=venues.`id`
where events.`id`!='e' order by events.`start_date` asc, venues.`name` limit 1");(相同的查询以纯SQL的形式运行,并将返回正确的值)知道这可能是什么吗?关联数组功能失败了吗?我实现查询的方式有问题吗?
ps: PDO不是选项,mysqlnd也没有安装.:(
附加问题
$res->fetch_object()一起去吗?发布于 2013-02-13 08:32:52
我刚修好了功能。也许这对其他人来说很有趣:
function connectDB($mysqli,$query,$v=array()) {
if($mysqli->connect_errno) {
return array('error'=>'Connect failed: '.$mysqli->connect_error); //error handling here
exit();
}
if(substr_count($query,"?")!=strlen($v[0])) {
return array('error'=>'placeholders and replacements are not equal! placeholders:'.substr_count($query,"?").' replacements:'.strlen($v[0]).' ('.$v[0].')'); //error handling here...
exit();
}
if($res=$mysqli->prepare($query)) {
//dynamically bind all $v
if($v) {
$values=array($v[0]);
for($i=1; $i<count($v); $i++) {
${'bind'.$i}=$v[$i];
$values[]=&${'bind'.$i};
}
call_user_func_array(array($res,'bind_param'),$values);
}
$res->execute();
//bind all table rows to result
if(strtolower(substr($query,0,6))=="select") {
$field=$fields=$tempRow=array();
$meta=$res->result_metadata();
while($field=$meta->fetch_field()) {
$fieldName=$field->name;
$fields[]=&$tempRow[$fieldName];
}
$meta->free_result();
call_user_func_array(array($res,"bind_result"),$fields);
//return associative array
$results=array();
$i=0;
while($res->fetch()) {
$results[$i]=array();
foreach($tempRow as $k=>$v) $results[$i][$k] = $v;
$i++;
}
$res->free_result();
}
else { //return infos about the query
$results["affectedRows"]=$mysqli->affected_rows;
$results["info"]=$mysqli->info;
$results["insertID"]=$mysqli->insert_id;
}
$res->close();
}
return $results;
}干杯
发布于 2013-02-12 07:48:02
Mysqli非常缺乏动态准备语句,这使得小抽象层的创建成为一场噩梦。
我强烈建议您切换到PDO或删除准备好的语句,并根据手动处理的占位符创建一个常规查询(首选)。
作为一个缓和补丁,您可以尝试使用get_result()函数,它将返回一个常规的结果变量,您可以使用fetch_assoc()遍历通常的方法。
但它只适用于mysqlnd构建。
还要注意,为每个查询创建mysqli对象是一个大的no-no。
创建一次,然后使用global $mysqli;在查询函数中分配它
这是不是开销太大了?
我不明白你在说什么
https://stackoverflow.com/questions/14827617
复制相似问题