4

PHP mysqli_result クラスは、しばらく前から Traversable インターフェースを実装しています。これにより、次のコードのような興味深い可能性が得られます。

<?php

$db = new mysqli( '...' );

$result = $db->query( '...' );

foreach( $result as $row ) {
   //$row is an associative array containing the fetched values
}

さて、私はこれをかなり気に入っていますが、現在取り組んでいるライブラリでは、連想配列ではなくオブジェクトを取得したいと考えています。クラスを渡すこともできるようにしたいので、それを使って簡単なモデルシステムを作成できます

そのために、次のように拡張します。

<?php

class mysqli_result_extension extends mysqli_result {

    protected $result_class;

    public function set_result_class( $class ) { $this->result_class = $class; }

    public function function_to_overwrite() {

        return $this->fetch_object( $this->result_class );
    }
}

私の問題とあなたへの質問:

fetch_assocからfetch_objectに切り替えるにはどうすればよいですか? Traversable インターフェイスが結果を返すために使用するメソッドを上書きしたいのですが、何も定義していません ( http://php.net/manual/en/class.traversable.php ) 。

fetch_assoc から fetch_object に切り替えて $result_class をそれに渡すことができるようにするには、何を上書きする必要があるので、次のようなことができます。

<?php

$db = new mysqli_extension( '...' );

$posts = $db->query( 'select * from posts' );
//$result is object of type mysqli_result_extension

$posts->set_result_class( 'post' );

foreach( $posts as $post ) {
   //$post is an instance of class 'post'
}

fetch_assoc を上書きしてその中のオブジェクトを返すような汚い、ハッキーなものは必要ありません

ご協力とご意見をお寄せいただきありがとうございます

4

3 に答える 3

0
ノート:

これは、PHP スクリプトで実装できない内部エンジン インターフェイスです。代わりに、IteratorAggregate または Iterator のいずれかを使用する必要があります。Traversable を拡張するインターフェースを実装するときは、implements 句の名前の前にIteratorAggregateまたはIteratorを必ずリストしてください。

つまり、インターフェース定義はhttp://docs.php.net/class.iteratorおよび/またはhttp://docs.php.net/class.iteratoraggregateにあります。

于 2012-11-16T14:02:46.347 に答える
0

コメントで述べたように、PDO でやりたいことを正確に行うのは簡単です。属性を設定するだけPDO::ATTR_DEFAULT_FETCH_MODEで、foreach ループを実行するときに適切な種類のフェッチが実行されます。

属性を設定して、PDO::ATTR_STATEMENT_CLASS使用するクラスを定義することもできます。

$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_CLASS);
$pdo->setAttribute(PDO::ATTR_STATEMENT_CLASS,array('classname',$constructorArgs));

詳細については、 http://php.net/manual/en/pdo.setattribute.phpを参照してください。

ATTR_STATEMENT_CLASSそのソリューションでは、インスタンス化するクラスに応じて、各クエリの属性を変更する必要があります。

または、クエリ内でクラス名を指定するように設定できます。

$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE);
$stmt = $db->query("SELECT 'classname', * FROM `table` WHERE `id` = 1;");

選択する最初のフィールドとして、関連するクラス名をクエリに追加するだけです。

この関連する質問の回答の 1 つを参照してくださいPHP では、デフォルトの PDO Fetch クラスを設定するにはどうすればよいですか? 詳細については。

于 2012-11-16T15:06:29.637 に答える