簡體   English   中英

動態mysqli准備好的語句失敗

[英]dynamic mysqli prepared statement fails

我試圖為我的mysqli連接編寫一個非常小的抽象層,但遇到了問題。 由於我維護的是舊代碼,因此我需要從查詢中獲取一個關聯數組,因為這是代碼的設置方式,因此一旦完成,對我來說將減少工作量...該函數適用於所有類型的查詢(不是只需選擇)...

我寫的函數是這樣的:

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()嗎?

Mysqli的動態預處理語句非常差,這使得小型抽象層創建成為噩夢。
我強烈建議您切換到PDO或放棄准備好的語句,並基於手動處理的占位符(首選)創建常規查詢。

作為姑息性補丁,您可以嘗試使用get_result()函數,該函數將返回一個常規結果變量,您可以使用fetch_assoc()以常規方式遍歷該變量
但是它僅適用於mysqlnd構建。

還要注意,為每個查詢創建mysqli對象是很大的禁止。
創建一次,然后使用global $mysqli;在查詢函數中分配它global $mysqli;

這是太多的開銷嗎

我不明白你在說什么開銷

我剛剛修復了功能。 也許這對其他人很有趣:

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;
}

干杯

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM