PHPの完全なコレクション

少し前まで、私たちのプロジェクトを開発するとき、同じタイプのオブジェクトを保存するための本格的なコレクションを実装するというアイデアが生まれました。

考え方は、異なるタイプのオブジェクトを含むコレクションは、たとえば、1つの統一されたコレクションタイプではなく、それ自体で区別されるということです。 つまり、タイプUserのオブジェクトのコレクションは、 Bookのオブジェクトのコレクションと同じではありません。 当然、最初の考えは、コレクション( UserCollectionBookCollection 、...)に異なるクラスを作成することでした。 ただし、データアプローチでは必要な柔軟性が得られず、すべてに加えて、そのような各クラスの宣言に時間を費やす必要があります。

少し考えてから、コレクションクラスの動的作成を実装しました。 このように見えます:ユーザーはBook型のオブジェクトのコレクションを作成し、目的のBookCollection型が自動的に作成されます(つまり、宣言されます)。



結果として私が得たもの:



-完全なTypeHintingはコレクションタイプを作成しました。

-コレクションの厳密な類型化。

-C#のように配列としてコレクションにアクセスすることが可能です( ArrayAccessインターフェースを実装することにより)

-コレクションの完全な反復(任意のサイクルで使用する機能)。



実装



回収工場



/** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  1. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  2. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  3. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  4. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  5. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  6. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  7. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  8. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  9. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  10. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  11. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  12. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  13. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  14. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  15. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  16. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  17. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  18. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  19. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  20. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  21. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  22. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  23. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  24. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  25. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  26. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  27. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  28. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  29. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  30. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



  31. /** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .



/** * * * @author [x26]VOLAND */ abstract class CollectionFactory { /** * . * * @param string $type * @return mixed */ public static function create($type) { $ class = $type . 'Collection' ; self::__create_class($ class ); $obj = new $ class ($type); return $obj; } /** * $class * * @param string $class * @return void */ private static function __create_class($ class ) { if ( ! class_exists($ class )) { eval( 'class ' . $ class . ' extends Collection { }' ); } } } * This source code was highlighted with Source Code Highlighter .







コレクションクラス(動作を説明)







  1. / **
  2. *コレクションクラス
  3. *どのコレクションが作成されるかに基づく基本的なユニバーサルタイプ。
  4. *
  5. * @author [x26] VOLAND
  6. * /
  7. 抽象 クラス CollectionはIteratorAggregate、ArrayAccess、Countableを実装します{
  8. / **
  9. *このコレクションに保存されているアイテムのタイプ。
  10. * @var string
  11. * /
  12. private $ __タイプ;
  13. / **
  14. *オブジェクトストレージ
  15. * @var配列
  16. * /
  17. private $ __ collection = array();
  18. // ------------------------------------------------ --------------------
  19. / **
  20. *デザイナー。
  21. *このコレクションに保存される要素のタイプを指定します。
  22. *
  23. * @param string $ type要素タイプ
  24. * @return void
  25. * /
  26. パブリック 関数 __construct($タイプ){
  27. $ this-> __ type = $ type;
  28. }
  29. // ------------------------------------------------ --------------------
  30. / **
  31. *オブジェクトのタイプを確認します。
  32. * `foreign`タイプのオブジェクトをコレクションに追加しないようにします。
  33. *
  34. * @param object $ objectチェックするオブジェクト
  35. * @return void
  36. * @throws例外
  37. * /
  38. プライベート 関数 __check_type(&$ object ){
  39. if (get_class($ object )!= $ this-> __ type){
  40. 新しい例外をスロー「オブジェクト型」 .. get_class($ object
  41. ``タイプのオブジェクトのコレクションに追加できません '' 。 $ this-> __タイプ。 '' ' );
  42. }
  43. }
  44. // ------------------------------------------------ --------------------
  45. / **
  46. *引数に渡されたオブジェクトをコレクションに追加します。
  47. *
  48. * @param object(s)オブジェクト
  49. * @return mixedコレクション
  50. * /
  51. パブリック 関数 add()
  52. {
  53. $ args = func_get_args();
  54. foreach ($ args as $ object ){
  55. $ this-> __ check_type($ object );
  56. $ this-> __ collection [] = $ object ;
  57. }
  58. $ thisを 返します。
  59. }
  60. // ------------------------------------------------ --------------------
  61. / **
  62. *引数から渡されたオブジェクトをコレクションから削除します。
  63. *
  64. * @param object(s)オブジェクト
  65. * @return mixedコレクション
  66. * /
  67. パブリック 関数 remove()
  68. {
  69. $ args = func_get_args();
  70. foreach ($ args as $ object ){
  71. unset($ this-> __ collection [array_search($ object 、$ this-> __ collection)]);
  72. }
  73. $ thisを 返します。
  74. }
  75. // ------------------------------------------------ --------------------
  76. / **
  77. *コレクションをクリーンアップします。
  78. *
  79. * @return mixedコレクション
  80. * /
  81. パブリック 関数 clear(){
  82. $ this-> __ collection = array();
  83. $ thisを 返します。
  84. }
  85. // ------------------------------------------------ --------------------
  86. / **
  87. *コレクションが空かどうかを調べます。
  88. *
  89. * @return bool
  90. * /
  91. パブリック 関数 isEmpty(){
  92. 空を返す ($ this-> __コレクション);
  93. }
  94. // ------------------------------------------------ --------------------
  95. / **
  96. * IteratorAggregateインターフェースの実装
  97. * /
  98. / **
  99. *イテレータオブジェクトを返します。
  100. *
  101. * @return CollectionIterator
  102. * /
  103. パブリック 関数 getIterator(){
  104. 新しい CollectionIteratorを返す ($ this-> __コレクション);
  105. }
  106. // ------------------------------------------------ --------------------
  107. / **
  108. * ArrayAccessインターフェースの実装。
  109. * /
  110. / **
  111. *コレクションの要素をオフセットに設定します
  112. *
  113. * @param ineter $ offsetオフセット
  114. * @param mixed $ offsetオブジェクト
  115. * @return void
  116. * /
  117. public function offsetSet($ offset、$ object ){
  118. $ this-> __ check_type($ object );
  119. if ($ offset === NULL){
  120. $ offset = max(array_keys($ this-> __ collection))+ 1;
  121. }
  122. $ this-> __ collection [$ offset] = $ object ;
  123. }
  124. // ------------------------------------------------ --------------------
  125. / **
  126. *指定されたキーを持つアイテムが存在するかどうかを調べます。
  127. *
  128. * @param integer $ offsetキー
  129. * @return bool
  130. * /
  131. パブリック 関数 offsetExists($ offset){
  132. return isset($ this-> __ collection [$ offset]);
  133. }
  134. // ------------------------------------------------ --------------------
  135. / **
  136. * $ offsetキーによって参照される要素を削除します。
  137. *
  138. * @param integer $ offsetキー
  139. * @return void
  140. * /
  141. パブリック 関数 offsetUnset($ offset){
  142. 設定解除($ this-> __コレクション[$オフセット]);
  143. }
  144. // ------------------------------------------------ --------------------
  145. / **
  146. *キーでアイテムを返します。
  147. *
  148. * @param integer $ offsetキー
  149. * @return mixed
  150. * /
  151. パブリック 関数 offsetGet($ offset){
  152. if (isset($ this-> __ collection [$ offset])=== FALSE){
  153. NULLを返します。
  154. }
  155. $ this-> __コレクション[$オフセット]を返します。
  156. }
  157. // ------------------------------------------------ --------------------
  158. / **
  159. * Countableインターフェースの実装
  160. * /
  161. / **
  162. *コレクション内の要素の数を返します。
  163. *
  164. * @return integer
  165. * /
  166. パブリック 関数カウント(){
  167. return sizeof ($ this- > __コレクション);
  168. }
  169. }
*このソースコードは、 ソースコードハイライターで強調表示されました。




使用例









  1. <?php
  2. クラス BookStore {
  3. 関数 addBooks(BookCollection $ books){
  4. //実装
  5. }
  6. 関数 addMagazines(MagazineCollection $ magazines){
  7. //実装
  8. }
  9. 関数 addGoods(コレクション$グッズ){
  10. //コレクションのタイプが重要でない場合、
  11. //コレクションのベースタイプを指定できます
  12. }
  13. }
  14. クラス Book {
  15. var $ id;
  16. function Book($ id){
  17. $ this-> id = $ id;
  18. }
  19. }
  20. クラス Magazine {
  21. var $ id;
  22. function Magazine($ id){
  23. $ this-> id = $ id;
  24. }
  25. }
  26. //コレクションを作成します
  27. $ books = CollectionFactory :: create( 'Book' );
  28. echo get_class($本); // BookCollection
  29. //オブジェクトをコレクションに追加します。
  30. $ books-> add( new Book(1)、 new Book(2));
  31. $ books-> add( new Book(3))-> add( new Book(2));
  32. $本[] = 新しい本(5);
  33. エコー数($本); // 5
  34. ...
  35. foreach ($本 $本として ){
  36. echo $ book-> id;
  37. } // 12345
  38. ...
  39. $ books-> add( new Magazine(1)); //エラー(間違ったタイプ)
  40. ...
  41. $ magazines = CollectionFactory :: create( 'Magazine' );
  42. $ magazines-> add( new Magazine(1));
  43. ...
  44. $ bookStore = new BookStore();
  45. $ bookStore-> addBooks($ books); //大丈夫
  46. $ bookStore-> addBooks($雑誌); //エラー(間違ったタイプ)
  47. $ bookStore-> addMagazines($雑誌); //大丈夫
  48. $ bookStore-> addGoods($ books); //大丈夫
  49. $ bookStore-> addGoods($雑誌); //大丈夫
  50. ?>
*このソースコードは、 ソースコードハイライターで強調表示されました。


ソースをダウンロード



All Articles