0

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()代わりに私が行くべきですか?
4

2 に答える 2

0

Mysqli は、動的なプリペアド ステートメントが非常に苦手なため、小さな抽象化レイヤーを作成するのは悪夢です。
PDO に切り替えるか、準備済みステートメントを削除して、手動で処理されるプレースホルダーに基づいて通常のクエリを作成することを強くお勧めします (推奨)。

get_result()一時的なパッチとして、通常の方法でトラバースできる通常の結果変数を返す関数の使用を試みることができますがfetch_assoc()
、mysqlnd ビルドでのみ機能します。

また、クエリごとに mysqli オブジェクトを作成することは絶対にダメです。
一度作成してから、次を使用してクエリ関数に割り当てますglobal $mysqli;

これはオーバーヘッドが大きすぎますか

あなたが話しているオーバーヘッドの意味がわかりません

于 2013-02-12T07:48:02.380 に答える
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;
}

乾杯

于 2013-02-13T08:32:52.140 に答える