【PHP8.x】CallbackFilterIterator::current()メソッドの使い方
currentメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
currentメソッドは、フィルタリング後のイテレータが指している現在の要素を返す処理を実行するメソッドです。このメソッドが所属するCallbackFilterIteratorクラスは、配列などの反復可能なデータ構造に対して、指定した条件(コールバック関数)に一致する要素だけを抽出するために使用されます。currentメソッドは、そのフィルタリング条件を満たした有効な要素のうち、イテレータの現在の位置にある値を具体的に取得する役割を担います。例えば、foreach構文を使ってイテレータをループ処理する際、各反復で個々の値を取り出すために、PHPの内部でこのメソッドが呼び出されます。イテレータのポインタはnextメソッドによって次の有効な要素へ移動し、currentメソッドがその要素の値を返します。このメソッドを直接呼び出す際は、事前にvalidメソッドで現在の位置が有効な要素を指しているかを確認することが一般的です。
構文(syntax)
1<?php 2 3$array = new ArrayIterator(['apple', 'banana', 'cherry', 'avocado']); 4 5// 'a' で始まる要素のみをフィルタリングするコールバック関数 6$filterCallback = function (string $current): bool { 7 return str_starts_with($current, 'a'); 8}; 9 10$iterator = new CallbackFilterIterator($array, $filterCallback); 11 12// イテレータをループ処理する 13foreach ($iterator as $value) { 14 // フィルタリングされた現在の要素を取得して表示する 15 // $value には $iterator->current() と同じ値が入る 16 echo $iterator->current() . PHP_EOL; 17} 18 19?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
mixed
CallbackFilterIterator::current()は、現在イテレータが指している要素を返します。この要素は、コールバック関数によってフィルタリングされた後、条件を満たした場合のみ取得できます。
サンプルコード
PHP: カレントディレクトリをフィルタリングして表示する
1<?php 2 3/** 4 * カレントディレクトリ内のファイルとディレクトリをフィルタリングして一覧表示します。 5 * 6 * このサンプルでは、CallbackFilterIteratorを使用して、 7 * カレントディレクトリを示す '.' と親ディレクトリを示す '..' を除外しています。 8 * コールバック関数の第一引数 $current には、イテレータの現在の要素が渡されます。 9 * これは、内部で CallbackFilterIterator::current() メソッドが返した値です。 10 */ 11function displayCurrentDirectoryContents(): void 12{ 13 // 1. カレントディレクトリのイテレータを作成 14 // DirectoryIterator は指定されたディレクトリ内のファイルやディレクトリを走査します。 15 try { 16 $directoryIterator = new DirectoryIterator('.'); 17 } catch (UnexpectedValueException $e) { 18 echo "ディレクトリを開けません: " . $e->getMessage() . PHP_EOL; 19 return; 20 } 21 22 // 2. CallbackFilterIterator を使用してイテレータをフィルタリング 23 // コールバック関数が true を返した要素のみが残ります。 24 $filterIterator = new CallbackFilterIterator( 25 $directoryIterator, 26 /** 27 * フィルタリング条件を定義するコールバック関数。 28 * 29 * @param SplFileInfo $current 現在のファイル/ディレクトリ情報 (DirectoryIterator::current() の戻り値) 30 * @param string $key ファイル名 31 * @param Iterator $iterator 元のイテレータ 32 * @return bool 要素を残す場合は true、除外する場合は false 33 */ 34 function (SplFileInfo $current, string $key, Iterator $iterator): bool { 35 // '.' や '..' のような特殊なディレクトリは除外する 36 return !$current->isDot(); 37 } 38 ); 39 40 echo "カレントディレクトリの内容 ('.' と '..' を除く):" . PHP_EOL; 41 echo "-------------------------------------------" . PHP_EOL; 42 43 // 3. フィルタリングされた結果をループ処理して表示 44 // foreachループは、内部で current() メソッドを呼び出して各要素を取得します。 45 foreach ($filterIterator as $fileInfo) { 46 // $fileInfo はフィルタリング後の現在の要素 (SplFileInfoオブジェクト) 47 $type = $fileInfo->isDir() ? '[DIR] ' : '[File]'; 48 echo $type . $fileInfo->getFilename() . PHP_EOL; 49 } 50} 51 52// 関数を実行します 53displayCurrentDirectoryContents(); 54
CallbackFilterIterator::current()メソッドは、フィルタリング後のイテレータが現在指し示している要素を取得するためのメソッドです。このメソッドに引数はなく、戻り値は現在の要素であり、その型は様々です(mixed型)。
このサンプルコードは、カレントディレクトリの内容から .(カレントディレクトリ自身)と ..(親ディレクトリ)という特殊なディレクトリを除外して一覧表示するものです。
まず、DirectoryIteratorを使ってディレクトリ内のファイルやディレクトリを順に処理するためのイテレータを作成します。次に、このイテレータをCallbackFilterIteratorに渡し、どの要素を残すかの条件をコールバック関数で定義します。
このコールバック関数の第一引数 $current には、DirectoryIteratorが指し示す現在のファイル情報(SplFileInfoオブジェクト)が渡されます。これは、CallbackFilterIteratorが内部で元のイテレータのcurrent()メソッドを呼び出した結果です。この $current を使ってファイルが . や .. でないことを判定し、条件に合うものだけを残します。
最後にforeachループで結果を一つずつ表示する際も、ループの内部で CallbackFilterIterator::current() が呼び出され、フィルタリングを通過した要素が変数 $fileInfo に代入されます。このように、current()メソッドはイテレータの現在の値を取得する上で中心的な役割を担います。
current()メソッドは、サンプルコード内で直接呼び出されてはいませんが、foreachループやコールバック関数の中で間接的に利用されています。CallbackFilterIteratorは、指定した条件で要素を絞り込むためのものです。コールバック関数の第一引数 $current には、現在処理対象となっているファイルやディレクトリの情報を持つオブジェクトが渡されます。これが内部的にcurrent()メソッドが返した値です。このオブジェクトが持つisDot()のようなメソッドを利用して、条件分岐で要素を残すか除外するかを判断します。また、new DirectoryIterator('.')の . はカレントディレクトリを指しますが、存在しない、またはアクセス権がない場合はエラーとなるため、try...catchによる例外処理を記述することが安全なプログラムには不可欠です。
PHPで現在の月イベントをフィルタリングする
1<?php 2 3/** 4 * 特定の月の予定のみをフィルタリングして表示するサンプルクラス。 5 * 6 * このサンプルは、CallbackFilterIteratorを使用して、 7 * 配列の中から「現在の月」に該当するデータのみを抽出する方法を示します。 8 */ 9class MonthlyEventViewer 10{ 11 /** 12 * @var array<DateTimeImmutable, string> イベントの日付と内容を格納する配列 13 */ 14 private array $events; 15 16 public function __construct() 17 { 18 // サンプルとして、様々な月を含むイベントデータを準備します。 19 $this->events = [ 20 new DateTimeImmutable('first day of -1 month') => '先月のレポート提出', 21 new DateTimeImmutable('today') => '今日のチームミーティング', 22 new DateTimeImmutable('first day of this month') => '今月のキックオフ', 23 new DateTimeImmutable('15th day of this month') => 'プロジェクト中間レビュー', 24 new DateTimeImmutable('first day of +1 month') => '来月の計画会議', 25 ]; 26 } 27 28 /** 29 * 現在の月のイベントをフィルタリングして表示します。 30 */ 31 public function displayCurrentMonthEvents(): void 32 { 33 // 現在の月の数値を取得します (例: '01', '02', ..., '12')。 34 $currentMonth = (new DateTimeImmutable())->format('m'); 35 36 // 配列をイテレータとして扱えるように、ArrayIteratorを作成します。 37 $iterator = new ArrayIterator($this->events); 38 39 // CallbackFilterIteratorは、指定した条件(コールバック関数)に合う要素だけを通過させるイテレータです。 40 $filterIterator = new CallbackFilterIterator( 41 $iterator, 42 // コールバック関数: 各要素のキー(日付)が現在の月と一致するかを判定します。 43 fn(string $value, DateTimeImmutable $key): bool => $key->format('m') === $currentMonth 44 ); 45 46 echo "今月のイベント一覧:\n"; 47 48 // フィルタリングされた結果をループで処理します。 49 // foreach ループは内部でイテレータの current() メソッドを自動的に呼び出し、 50 // 条件に一致した現在の要素の値 (この場合はイベント名) を取得します。 51 foreach ($filterIterator as $date => $eventName) { 52 // $eventName は $filterIterator->current() が返した値です。 53 // $date は $filterIterator->key() が返した値です。 54 echo sprintf(" - %s: %s\n", $date->format('Y-m-d'), $eventName); 55 } 56 } 57} 58 59// クラスのインスタンスを作成し、メソッドを実行します。 60$viewer = new MonthlyEventViewer(); 61$viewer->displayCurrentMonthEvents(); 62
CallbackFilterIterator::current()は、フィルタリング条件に一致したイテレータの現在の要素の「値」を取得するメソッドです。
このサンプルコードは、CallbackFilterIteratorを用いて、様々な日付のイベントが格納された配列から「現在の月」のイベントデータだけを抽出する例を示しています。フィルタリングの条件は、コンストラクタの第二引数に渡されたコールバック関数によって定義され、各要素のキーである日付オブジェクトの月が、現在の月と一致するかを判定します。
foreachループで$filterIteratorを処理する際、ループが次の有効な要素に進むたびに、内部でcurrent()メソッドが自動的に呼び出されます。そして、その戻り値がループ変数 $eventName に格納されます。例えば、条件に一致した要素が '今日のチームミーティング' という値を持つ場合、current()はその文字列を返します。
このメソッドは引数を取りません。戻り値の型はmixedで、元となるデータ構造の値の型に依存します。このサンプルでは、イベント名である文字列が返されます。このようにcurrent()は、フィルタリングされた結果の中から、現在指し示している要素の値を取り出す重要な役割を担っています。
foreachループは、条件に合う要素が見つかるたびに、内部でCallbackFilterIteratorのcurrent()メソッドを自動で呼び出し、その要素の値を取得します。そのため、開発者が明示的にcurrent()を記述する必要はありません。このフィルタリングの核となるコールバック関数は、trueを返した要素だけを通過させます。関数の引数は、第1引数が要素の値、第2引数がキーという順番で渡される点に注意してください。また、このコードでは日付の月をformat('m')で文字列として取得し、厳密な比較演算子===を使用しています。これにより、型と値の両方が一致することを確認でき、より安全な判定が可能です。