2013-02-12 166 views
0

我想爲我的mysqli連接寫一個非常小的抽象層,並且遇到了問題。 因爲我維護較舊的代碼,我需要從我的查詢中獲得一個關聯數組,因爲這是代碼已經設置的方式,因此一旦這種方式工作對我來說更少... 此函數適用於各種查詢(不只是選擇)...動態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()呢?

回答

0

我給你在你的查詢功能只是修復了這個功能。 也許這是別人有意思:

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

歡呼

0

的mysqli是很差,動態準備的語句,這使得小抽象層創建一個噩夢。
我強烈sugges您可以切換到PDO或擺脫準備好的語句,並根據手動處理的佔位符創建常規查詢(首選)。

爲緩解補丁,你可以嘗試使用get_result()函數會返回一個常規結果變量,你可以穿越通常的方式與fetch_assoc()
但它僅適用於mysqlnd建立。

另請注意,爲每個查詢創建mysqli對象是一個很大的禁忌。
創建一次,然後用global $mysqli;

這是太多的開銷

我不明白你在說什麼開銷約

+0

謝謝!我只是將實例化移入該示例的函數中。沒有任何活代碼我同意! (請不要我的編輯) – Dominik 2013-02-12 08:44:40

+0

我建議你使用我的抽象庫,而不是寫你自己的。這是更有用,並始終工作。您可以在我的個人資料中找到鏈接。如果你想堅持自己的 - 好吧,調試它。 – 2013-02-12 09:20:35