配列またはオブジェクト? PHPのコレクションが欲しい!

本当に隠すものは、私はオブジェクトが好きで、連想配列は好きではありません。 そして、データベースからデータセットを選択するとき、配列の配列ではなくオブジェクトのセットを取得したいです。 そして、単なるオブジェクトのセットではなく、私が必要とするセットと、私が望むだけの方法です。 以前は、ベースから3段階の選択がありました。

1.データベースからデータの配列を取得する

2.結果を確認する

3.各反復でオブジェクトを作成し、別の配列に入れます

さて、実際にデータを返します。 それほど面倒ではありませんが、もっと簡単で便利な方法があるはずだと感じました。 そして、私はそれを見つけました-コレクション。



コレクションが大好きです。 特定のオブジェクトで、同じタイプのデータの配列が常に必要でした。 特にデータベースと組み合わせて。

最も一般的な状況-データベースからUserオブジェクトの配列を取得したい:

Db_users :: getAll()メソッド

1.データベースからデータを読み取る

2.結果の配列を調べて、各行をユーザーオブジェクトに移動します

3.受け取ったUserオブジェクトを別の配列に保存します

このようなことが起こります:

static public function getAll() { $result = array(); $data = $this->db->fetchAll(); foreach( $data as $row ) { $user = new User( $row ); $result[] = $user; } return $result; }
      
      





ここには、データベースからすべてのユーザーを取得し、エンティティの配列を返す、このような単純で標準的なメソッドがあります。

そして、どういうわけか、これはテンプレートに表示されます:

 <html> <head> <title>Users list</title> </head> <body> <table> <th> <td>User ID</td> <td>User login</td> <td>User email</td> <td>User name</td> </th> <?php foreach( $users as $user ): ?> <tr> <td><?php echo $user->id; ?></td> <td><?php echo $user->login; ?></td> <td><?php echo $user->email; ?></td> <td><?php echo $user->name; ?></td> </tr> <?php endforeach; ?> </table> </body> </html>
      
      





そして絶えず。 すべてがうまく機能しているように見えますが、何かが間違っています。 最初に目を引くのは2サイクルです。 最初はエンティティの配列を作成するとき、2番目は出力するときです。 (大まかに言って)同じ配列の2つのループ-なぜですか? 最初の考えはPDOです!

はい、彼には魔法のfetchObjメソッドがあります。 多くの人に適していますが、その機能の1つが好きではありません。

 class A { public function __construct() { echo "<br>construct"; } public function __set($key, $val) { echo "<br>setter"; } } $pdo = new PDO('mysql:dbname=home;host=127.0.0.1', 'root'); $sql = 'SELECT id FROM `table`'; $res = $pdo->query($sql); var_dump( $res->fetchObject('A') );  : setter setter constructobject(A)#3 (0) { }
      
      





(PDO :: FETCH_PROPS_LATEについて教えてください。これにより、コンストラクターを呼び出す前にプロパティを設定する問題が解決します。)

これが問題にならない場合は、そこで停止できます。プロパティを設定した後、コンストラクターが呼び出されることは適切ではありません(別のクラスとしてコンストラクターでフィルターを作成し、空の変数をチェックして松葉杖を挿入したくない)、すべてのフィールドがプロパティとして設定されましたそれでは先に進みましょう。

ArrayIteratorという優れた組み込みソリューションがあります。 配列のようなゲッターとセッター、およびforeachで反復処理する機能を備えた、このような優れたオブジェクト。 必要なものだけ。

 class Collection extends ArrayIterator { }
      
      





getAllメソッドを少し変更します。

 static public function getAll() { $result = array(); $data = $this->db->fetchAll(); $result = new Collection( $data ); return $result; }
      
      





そしてテンプレート:

 <?php foreach( $users as $user ): ?> <tr> <td><?php echo $user['id']; ?></td> <td><?php echo $user['login']; ?></td> <td><?php echo $user['email']; ?></td> <td><?php echo $user['name']; ?></td> </tr> <?php endforeach; ?>
      
      





すでに優れていますが、このコレクションは何ですか? 単なるコピーされた配列です。 あまり面白くない。 オブジェクト、さらには完全なオブジェクトを受け取りたいです。

メソッドArrayIterator :: offsetGet(配列のようにキーでアクセス)およびArrayIterator :: current(foreachを反復して現在の関数で要素を受け取るときにアクセス)のメソッドを見て、これらのメソッドはそれぞれ、キーで値を、内部ポインターで現在の要素を、必要なもの、再定義:

 public function offsetGet( $index ) { if( empty( $this->_cache[$index] ) ) { //    $this->_cache[$index] = new User( parent::offsetGet[$index] ); } return $this->_cache[$index]; } public function current( ) { $index = parent::key(); if( empty( $this->_cache[$index] ) ) { //    $this->_cache[$index] = new User( parent::current() ); } return $this->_cache[$index]; }
      
      





その結果、テンプレートは思い通りになりました。

 <?php foreach( $users as $user ): ?> <tr> <td><?php echo $user->id; ?></td> <td><?php echo $user->login; ?></td> <td><?php echo $user->email; ?></td> <td><?php echo $user->name; ?></td> </tr> <?php endforeach; ?>
      
      





まあ、すべてが大丈夫のようで、不要なサイクルを取り除き、配列をオブジェクトに置き換えました

最後に、返されたクラスを動的に追加できます。



All Articles