0

PHP 5.2.17

mysqli の準備済みステートメントの結果は、変数にバインドされます。

カスタム fetchAll メソッドを追加するために mysqli_stmt を拡張したい。

なんで?プリペアド ステートメント データベースの結果に対して同じ while ステートメントを記述するのをやめ、コードを mysqli 自体に含めて、すべての呼び出しで自動的に処理されるようにしたいためです。また、独自の特別なコードとフィルターも追加します。

mysqli クラスを拡張し、準備されていないステートメントに対してこれを行うカスタム処理を追加することができましたが、これを準備済みステートメントの処理に追加したいと考えています。

stackoverflow やその他の場所を読んで、mysqli_stmt を拡張する例をいくつか見つけましたが、php 5.2x の fetchAll タイプのカスタム メソッドを追加することに似たものはありませんでした。

私はこれがどのように機能するのか理解していません。私はOOPとコアphpクラスの拡張に少し慣れていないので、学べるようにできるだけ多くの説明をいただければ幸いです。

私のウェブホストにはphp 5.2.17があり、それを制御できないため、phpをアップグレードすることはできません。PDO、mysqli、および mysql データベース接続を処理するクラスを作成しました。私は今これを最適化しようとしており、関連する領域に可能な限りカプセル化して移動しているため、これを行うことに関心があります。

結果クラスについては理解していますが、準備済みステートメントのフェッチの処理は、結果を取得するためのフェッチのみを持つ mysqli_stmt クラスを介して行われることがわかります。私はこのクラス内から結果を得ることができず、外部からのみ結果を得ることができました. バインディングまたはパラメーターと変数が原因だと思います。ただし、ここでのプロセスは正確にはわかりません。

また、返される結果は変数にバインドされており、これらは while ループを介して更新されます。このプロセスを取得して stmt クラス内に配置したいのですが、これを行う方法がわかりません。

ご協力いただきありがとうございます。私はかなり頭がいいですが、このプロセスを理解するのに苦労しているので、うまく説明できれば幸いです.

ありがとう。

編集:

これに追加して、いくつかのコードを表示したいと思います。

$mysqli->execute();     
$mysqli->store_result();
$mysqli->bind_result($id, $name, $age);                     

$i = 0;
While($mysqli->fetch()){            
    $array[$i]['id'] = $id;
    $array[$i]['age'] = $age;
    $array[$i]['name'] = $name;
    $i++;
}           
                    
return $array;

                    

While ステートメントを見てください。

ここで、それを MYSQLI_STMT クラスに配置して、何度も何度も記述する必要がないようにします。MYSQL_STMT クラスに処理させます。

これは、FetchALL と呼ばれる新しいメソッドに入ります。問題は、うまくいかないことです。これは準備されたステートメントであるため、ステートメントと SQL は、この時点に到達してもまだ準備されていません。

私はこのようなことをするためのこのプロセスを理解していません。

以下は私が編集したコードであり、私が作成したものではありません。どこで入手したのか、誰が作者なのかは忘れましたが、次のコードの功績は認めていません。元のバージョンから何かを変更し、質問/問題に関係のないものをすべて取り出しました。

class my_mysqli_stmt extends mysqli_stmt{

public function __construct($link, $query) {
    parent::__construct($link, $query);
}  

public function fetchAll(){

    echo "FetchAll Method";

    while($this->fetch()){
        # Nothing happens here
        # and don't know what 
        # to insert here if it did  
    }
  }
}


class my_Mysqli extends mysqli {

    public function prepare($query) {
        return new my_Mysqli_stmt($this, $query);
    }
}

上記の WHILE ステートメントを含むコード ブロックは、次のように置き換えられます。

$mysqli->execute();        
$mysqli->store_result();
$mysqli->bind_result($id, $name, $age);     

$mysqli->fetchAll();   <--  This would replace the WHILE loop.

もちろん、これは機能しません。このように動作することを意図したものではないかもしれませんが、while ループが不要になり、その 1 回の呼び出しですべてのレコードが返されるようにすることができればいいと思います。

これをコードで見ると、この概念は私の考え方がずさんなように思えますが、すべてのコードを 1 か所にカプセル化することは素晴らしいことです。

多分次のようなことをしてください:

$mysqli->fetchAll($id, $name, $age); 

バインドされたパラメーターを返しますか? 私は今自分自身を混乱させていることを知りません。

わかりました、これを見直しました..

Fetch ループが発生するたびに、パラメータはデータベースから取得した行の関連データで自動更新されます。

ここで起こること、またはすべきことは、FetchAll が呼び出されると、すべてのバインドされたパラメーターとデータを含む連想配列が返されるため、この直後に MYSQLI_STMT クラス内で作成された配列を返し、FetchAll に返されることです。から。

バム!Presto Chango と取得されたすべてのレコードは連想配列にあり、すぐに使用できます。ほら、すべてカプセル化されています。問題は..どのように?それを機能させることはできません。

この質問の墓を読んでくれてありがとう。

4

2 に答える 2

1

これはかなり可能です。必要なのは、 PDOに切り替える
ことだけです

PDO には、mysqli から必要なものがすべて揃っているほかfetchAll、すぐに使用できるbindValue(!!!) bind-in-executefetchColumn...

mysqli を使用する運命にある場合、できることはあまりありません。fetch_all()連想配列または列挙配列のいずれかを取得できる組み込み関数があります。

于 2013-03-05T12:58:44.253 に答える
0

バインドされた変数にアクセスする方法がないため、これは可能ではないと思います (私は PHP 5.4.4 を実行しています)。

あったとしても、によって返される値のそれぞれに、どのバインドされた変数を割り当てる必要があるかを暗黙のうちに伝えるのは困難です。fetch()

関数をオーバーロードしようとしbind_result()ましたが (以下を参照)、変数が参照として渡されるため、問題が発生しました。

public function bind_result() {
    $this->bound_variables = func_get_args();

    // The next line won't work in < 5.3
    call_user_func("parent::bind_result", $this->bound_variables);
}

そのため、次のエラーが発生しました。Warning: Parameter 1 to mysqli_stmt::bind_result() expected to be a reference, value given...

クラスの代わりにfetchAllasを追加しようとしましたが、バインドされた変数を参照として取得できず、値としてのみ取得できないため、失敗しました。my_Mysqlimy_mysqli_stmt

class my_Mysqli extends mysqli {

    public function prepare($query) {
        return new my_Mysqli_stmt($this, $query);
    }

    private $bound_vars;

    public function fetchAll($statement) {

        $args = func_get_args();
        $first = true;
        // Even though we try using 'by reference' here, the arguments themselves
        // are passed in 'by value' by default (because we haven't specified them
        // in the function definition)
        foreach($args as &$a) {
            if ($first) { continue; $first = false; }
            $this->bound_vars[] = $a;
        }

        while($statement->fetch()){
            // This doesn't work, because we haven't got references back to
            // the original variables
            printf ("%s (%s)\n", $this->bound_vars[0], $this->bound_vars[1]);
        }
    }
}
$mysqli = new my_Mysqli();
$stmt = $mysqli->prepare($query);
$stmt->execute();
$stmt->bind_result($id, $age, $name);
$mysqli->fetchAll($stmt, $id, $age, $name);
于 2013-03-05T12:49:12.077 に答える