Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】InfiniteIterator::__construct()メソッドの使い方

__constructメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

__constructメソッドは、指定されたイテレータを無限に繰り返すInfiniteIteratorの新しいインスタンスを生成し、初期化を実行するメソッドです。このメソッドはクラスのコンストラクタとして機能し、InfiniteIteratorオブジェクトが作成される際に自動的に呼び出されます。引数には、Iteratorインターフェースを実装したイテレータオブジェクトを一つ指定する必要があります。コンストラクタは、この渡されたイテレータを内部的に保持します。生成されたInfiniteIteratorのインスタンスをforeachループなどで使用すると、内部のイテレータが末尾の要素に達した際に、自動的に先頭へ巻き戻されます。これにより、元のイテレータの要素シーケンスを無限に繰り返し処理することが可能になります。例えば、ArrayIteratorを渡すことで、配列の要素を循環的にアクセスするような処理を簡単に実装できます。

構文(syntax)

1public __construct(Iterator $iterator)

引数(parameters)

Iterator $iterator

  • Iterator $iterator: 無限に繰り返したいイテレータオブジェクト

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

PHP 8 コンストラクタプロモーションで無限イテレータを扱う

1<?php
2
3// 元になるデータ
4$data = ['Apple', 'Banana', 'Cherry'];
5
6// ArrayIteratorを使ってデータをイテレータとして扱えるようにします
7$arrayIterator = new ArrayIterator($data);
8
9// InfiniteIteratorはArrayIteratorを無限に繰り返すイテレータとしてラップします
10$infiniteIterator = new InfiniteIterator($arrayIterator);
11
12/**
13 * InfiniteIteratorを内部に持ち、PHP 8のコンストラクタプロモーションを利用するクラスです。
14 *
15 * コンストラクタプロモーションにより、コンストラクタの引数とプロパティの宣言・初期化が
16 * 一つのコード行で行われます。
17 */
18class MyIteratorContainer
19{
20    /**
21     * PHP 8のコンストラクタプロモーションの利用例。
22     * 引数 $iterator が private プロパティ $this->iterator として自動的に宣言・初期化されます。
23     *
24     * @param InfiniteIterator $iterator 無限イテレータのインスタンス
25     */
26    public function __construct(
27        private InfiniteIterator $iterator // ここで可視性と型ヒントを指定することでプロパティとして昇格
28    ) {
29        // コンストラクタ本体には、追加のロジックが不要であれば空で問題ありません
30    }
31
32    /**
33     * 無限イテレータから指定された回数だけ要素を反復処理し、表示します。
34     *
35     * @param int $limit 反復処理を行う最大回数
36     */
37    public function displayLimitedItems(int $limit): void
38    {
39        echo "無限イテレータからの要素(最大 {$limit} 回):\n";
40        $count = 0;
41        // 内部のInfiniteIteratorをforeachで反復処理します
42        foreach ($this->iterator as $item) {
43            echo "- " . $item . "\n";
44            $count++;
45            if ($count >= $limit) {
46                break; // 無限ループになるため、指定回数でループを停止します
47            }
48        }
49    }
50}
51
52// MyIteratorContainerのインスタンスを作成します。
53// ここで $infiniteIterator が MyIteratorContainer のプライベートプロパティとして
54// コンストラクタプロモーションによって宣言・初期化されます。
55$container = new MyIteratorContainer($infiniteIterator);
56
57// 無限イテレータの要素を限定的に表示します(例: 7回)
58$container->displayLimitedItems(7);
59
60?>

このPHPのサンプルコードは、InfiniteIteratorクラスの利用方法と、PHP 8で導入された「コンストラクタプロモーション」という便利な機能を示しています。

InfiniteIteratorは、その名の通り、指定されたイテレータの要素を無限に繰り返し提供するクラスです。そのコンストラクタである__constructメソッドは、引数としてIteratorインターフェースを実装したインスタンス(この例ではArrayIterator)を受け取ります。この引数が、無限に繰り返される元のデータ源となります。__constructはインスタンスを初期化する目的で使用され、特定の値を返しません。

サンプルコード中のMyIteratorContainerクラスは、InfiniteIteratorのインスタンスを内部に保持し、その機能を利用します。ここで注目すべきは、MyIteratorContainer__constructメソッドです。PHP 8の「コンストラクタプロモーション」という機能により、private InfiniteIterator $iteratorのように引数を宣言するだけで、その引数が自動的にプライベートプロパティ$this->iteratorとして宣言され、同時に初期化されます。これにより、コンストラクタ内でプロパティを改めて定義し、代入するといった記述が不要になり、コードをより簡潔に記述できます。

最終的に、MyIteratorContainerdisplayLimitedItemsメソッドは、内部のInfiniteIteratorから要素を取得し、指定された回数だけ表示します。InfiniteIteratorが無限に要素を返すため、ループ内で明示的に回数制限を設けて停止させている点が重要なポイントです。

このコードではInfiniteIteratorが名前の通り要素を無限に繰り返すため、foreachで利用する際は必ずbreakなどを用いて停止条件を設ける必要があります。そうしないと無限ループに陥り、プログラムが停止しなくなる点に注意してください。また、MyIteratorContainerクラスのコンストラクタで使われているprivate InfiniteIterator $iteratorは、PHP 8から導入された「コンストラクタプロモーション」という機能です。これは、コンストラクタの引数で直接プロパティの宣言と初期化を同時に行うもので、コードを簡潔に書くことができます。ただし、PHP 7以前の環境では動作しませんので、利用するPHPのバージョンを確認してください。引数にIteratorInfiniteIteratorといった型ヒントを指定することで、期待される型の引数のみを受け入れ、堅牢なコードになります。

PHP 8 プロパティプロモーションと InfiniteIterator の使い方

1<?php
2
3/**
4 * InfiniteIterator の使用例と PHP 8 のコンストラクタプロパティプロモーションを示すクラス。
5 *
6 * このクラスは、コンストラクタで Iterator を受け取り、それをプロパティプロモーションによって
7 * クラスの内部プロパティとして宣言・初期化します。その後、そのイテレータを利用して
8 * InfiniteIterator を作成し、無限ループのデモンストレーションを行います。
9 */
10class MyInfiniteIteratorProcessor
11{
12    /**
13     * PHP 8 のコンストラクタプロパティプロモーションを使用して、
14     * 引数として受け取った Iterator オブジェクトをプライベートプロパティ $internalIterator として宣言・初期化。
15     * これにより、引数の宣言、プロパティの宣言、プロパティへの代入を1行で記述できます。
16     *
17     * @param Iterator $internalIterator InfiniteIterator に渡す元のイテレータ
18     */
19    public function __construct(private Iterator $internalIterator)
20    {
21        // プロパティプロモーションにより、$this->internalIterator が既に初期化されています。
22        // ここでは追加の初期化や設定は不要です。
23    }
24
25    /**
26     * InfiniteIterator の動作をデモンストレーションします。
27     * 無限イテレータの要素を、指定された回数だけ処理して出力します。
28     *
29     * @param int $limit 処理する要素の最大数。無限ループを防ぐために使用します。
30     */
31    public function demonstrateInfiniteIteration(int $limit = 5): void
32    {
33        echo "=== InfiniteIterator デモンストレーション ===\n";
34        echo "元のイテレータの要素: ";
35        foreach ($this->internalIterator as $value) {
36            echo "{$value} ";
37        }
38        echo "\n\n";
39
40        // プロモートされた $this->internalIterator を使用して InfiniteIterator をインスタンス化
41        $infiniteIterator = new InfiniteIterator($this->internalIterator);
42
43        echo "InfiniteIterator から最初の {$limit} 個の要素を取得:\n";
44        $count = 0;
45        foreach ($infiniteIterator as $key => $value) {
46            echo "  キー: {$key}, 値: {$value}\n";
47            $count++;
48            if ($count >= $limit) {
49                break; // 無限ループを停止
50            }
51        }
52        echo "\nデモンストレーション終了。\n";
53    }
54}
55
56// --- サンプルコードの実行 ---
57
58// 元になるデータを格納した ArrayIterator を準備
59// InfiniteIterator は内部のイテレータを無限に繰り返します。
60$data = ['Hello', 'PHP', '8'];
61$arrayIterator = new ArrayIterator($data);
62
63// MyInfiniteIteratorProcessor クラスのインスタンスを作成
64// コンストラクタに ArrayIterator を渡し、PHP 8 のプロパティプロモーションにより
65// $internalIterator プロパティが自動的に初期化されます。
66$processor = new MyInfiniteIteratorProcessor($arrayIterator);
67
68// InfiniteIterator の動作をデモンストレーション
69// 元の要素数 (3) よりも多い回数 (7) を指定することで、
70// InfiniteIterator が要素を繰り返していることを確認できます。
71$processor->demonstrateInfiniteIteration(7);
72
73?>

このサンプルコードは、PHP 8で導入された「コンストラクタプロパティプロモーション」の利用例と、InfiniteIteratorクラスの基本的な使い方を示しています。InfiniteIteratorは、渡されたIteratorオブジェクトの要素を無限に繰り返す機能を提供し、そのコンストラクタである__constructメソッドは、引数として反復させたい元のIteratorを受け取ります。このメソッドに特定の戻り値はありません。

サンプルコード内のMyInfiniteIteratorProcessorクラスの__constructメソッドでは、private Iterator $internalIteratorという形式で引数を宣言しています。これがPHP 8のコンストラクタプロパティプロモーションです。この記述により、引数の宣言と同時に、同名のプライベートプロパティ$internalIteratorが自動的に定義され、引数の値で初期化されます。これにより、プロパティの宣言、コンストラクタでの引数受け取り、そしてプロパティへの値の代入という一連の処理を1行で簡潔に記述できるようになります。

クラス内部では、このプロモートされた$this->internalIteratorプロパティをInfiniteIteratorのコンストラクタに渡し、無限に反復するイテレータを作成します。demonstrateInfiniteIterationメソッドでは、このInfiniteIteratorが元のイテレータの要素をどのように繰り返し出力するかを、指定された回数まで処理して示しています。これにより、コンストラクタで受け取ったイテレータがクラス内でどのように活用されるかが理解できます。

InfiniteIteratorは名前の通り無限に要素を繰り返しますので、foreachなどで利用する際は、サンプルコードのように必ず明示的な停止条件を設けてください。これを怠るとプログラムが無限ループに陥り、フリーズする可能性があります。PHP 8で導入されたコンストラクタプロパティプロモーションは、コンストラクタ引数でプロパティの宣言、アクセス修飾子の指定、初期化を同時に行います。これによりコードが簡潔になりますが、__constructメソッドの本体内で改めて$this->プロパティ = 引数;と代入する必要はありません。また、InfiniteIteratorのコンストラクタには、Iteratorインターフェースを実装したオブジェクトのみを渡す必要がありますので、引数の型に注意してください。

関連コンテンツ