質問するログイン新規登録

Q&A

解決済

2回答

109閲覧

PHP8「DirectoryIterator クラスは SeekableIterator を実装している」についての疑問

nanigasi

総合スコア21

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2026/04/26 02:04

0

0

PHP8.0上級試験の勉強をしています。
その中で分からないことがあったため、お聞きしたいです。

前提

模擬試験ページ https://study.prime-strategy.co.jp/study/ph8ex1/

模擬試験 問22 のある選択肢の中で、

“DirectoryIterator クラスは、SeekableIteratorを実装しているため foreach などが使える。”

という記述があります。

そして公式アニュアル https://www.php.net/manual/ja/class.directoryiterator.php
を読む限り、

PHP

1class DirectoryIterator extends SplFileInfo implements SeekableIterator {...}

の記述があるため、問題文のその一文は正しいと考えています。

疑問

しかし模擬試験について解説している2つのブログ記事ではどちらも
「DirectoryIterator は SeekableIterator を 実装していません。」と言い切っています。

【php8上級/準上級試験】模擬問題解説 問題22. Directory DirectoryIterator SeekableIterator – ntorelabo
https://ntorelabo.com/%E3%80%90php8%E4%B8%8A%E7%B4%9A-%E6%BA%96%E4%B8%8A%E7%B4%9A%E8%A9%A6%E9%A8%93%E3%80%91%E6%A8%A1%E6%93%AC%E5%95%8F%E9%A1%8C%E8%A7%A3%E8%AA%AC-%E5%95%8F%E9%A1%8C22-directoryiterator-seekableiterator/

【やさしく解説】PHP8上級試験の模擬問題(22) | TechNote
https://technote7.com/php8_mogi22/

公式マニュアルと突き合わせると「解説記事の方が怪しい」と思っていますが、
同意見の解説者が二人も居ることと、自分が未熟である点から、中々正解が分からずにいます。

かなり考えづらいことではありますが、
「公式マニュアルが完全に正しい」としたうえで、
「解説ブログ + 模擬試験」どちらも間違って捉えている可能性、、も考慮しています。

補足

PHP8上級試験が「8.1以降は試験に含まれない」ことから新しい仕様かと思いましたが、
本件の仕様は少なくともVer7から存在しているようです。
そのためバージョン差異による解説のズレでは無いと考えています。

質問内容

このことについて、何が誤りか、質問者(私)が何か誤解しているのか、
分かる方いましたら是非ご教示ください。

言葉足らずな点ありましたらご指摘いただきたいです。
追記いたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

guest

回答2

0

ベストアンサー

選択3が誤りであるというのが正しい回答であれば、説明が雑で厳密にはこうだから違う、と寄せることは可能です。
しかし、選択4の方がより実際の挙動と異なっており、設問としてはあまり良くないように思います。

選択3について

SeekableIteratorを実装しているため foreach などが使える。

SeekableIteratorを実装しているというのは正しいです。

foreach が使える理由としては厳密には Traversableインターフェイス を継承したクラスを実装しているためです。
SeekableIteratorは Iterator を継承し、Iterator は Traversable を継承しているため、結果として foreach で反復できます。
そのため、「SeekableIteratorを実装しているため foreach などが使える」という説明はやや雑ですが、完全な誤りとは言いにくいです。

また SplFileInfo クラスには __toString() が実装されているため、ファイルへのパスを文字列で返すことが出来る。

__toString() が実装されているというのは正しいです。

ただし、DirectoryIterator の各要素を文字列化した場合、返るのはファイル名のみです。
カレントディレクトリからアクセス可能なパスとしての文字列は Getpathname()メソッド で取得します。

「ファイルへのパスを返す」という表現は不正確ではありますが、SplFileInfo::__toString() の公式説明にも “ファイルへのパスを文字列で返す” という表現があるため、これだけを明確な誤りと断定するのはやや難しいです。

選択4について

/home/php_exam/.cache /home/php_exam/.config /home/php_exam/.bashrc /home/php_exam/Beginner /home/php_exam/Beginner/sample /home/php_exam/Beginner/src /home/php_exam/Beginner/src/1.php /home/php_exam/Beginner/src/2.php (略) /home/php_exam/Advanced /home/php_exam/Advanced/sample /home/php_exam/Advanced/src (以下略)

のような表記になり、とありますが、これはこの通りにはなりません。

RecursiveIteratorIterator クラスのデフォルト挙動は LEAVES_ONLY です。
ディレクトリの中は再帰的に探索しますが、子を持つ通常のディレクトリ自体は foreach の値としては出力されません。
一方で RecursiveDirectoryIterator はデフォルトでは ... を含めるため、各ディレクトリ配下の ... は出力されます。
実際には下記のような出力になります。
(順序は保証されていないのでファイルシステムによって異なる可能性はあります)

/home/php.exam/. /home/php.exam/.cache/. /home/php.exam/.cache/.. /home/php.exam/Advanced/src/. /home/php.exam/Advanced/src/.. /home/php.exam/Advanced/. /home/php.exam/Advanced/sample/. /home/php.exam/Advanced/sample/.. /home/php.exam/Advanced/.. /home/php.exam/.bashrc /home/php.exam/sample.php /home/php.exam/.config/. /home/php.exam/.config/.. /home/php.exam/Beginner/src/. /home/php.exam/Beginner/src/1.php /home/php.exam/Beginner/src/2.php /home/php.exam/Beginner/src/.. /home/php.exam/Beginner/. /home/php.exam/Beginner/sample/. /home/php.exam/Beginner/sample/.. /home/php.exam/Beginner/.. /home/php.exam/..

所感

選択3は表現が不正確ではあるものの、公式ドキュメント上の表現とも完全には矛盾しないため、誤りとしてはやや弱く感じます。

一方、選択4は RecursiveIteratorIterator のデフォルトモードが LEAVES_ONLY である点と、RecursiveDirectoryIterator がデフォルトで ... を含む点から、提示されている出力例と実際の挙動が明確に異なります。

そのため、個人的には選択4の方が誤りと思えます。

投稿2026/04/26 11:44

Eggpan

総合スコア3312

nanigasi

2026/04/27 12:20

他選択肢までお調べいただき、ありがとうございます! とても参考・勉強になりました。 若干曖昧なニュアンスもある類の問題、、、としてあまり深入りしないように留意しつつ、学習を進めます。 迷っていたので本当に助かりました、 改めて、ありがとうございました!
guest

0

運転免許並みに嫌らしい問題ですね。
「選択肢3が誤りである」が正解であるという前提で考えると、foreachが使える理由は「SeekableIteratorを実装しているため」ではなく、Iteratorを実装しているためです。
SeekableIteratorはIteratorを継承していますが、foreachが使える理由としては別にSeekableでなくてもよい、という設問意図なのでしょうか。

DirectoryIteratorは、Iteratorを継承したSeekableIteratorを実装しているのでイテレータとして使える、と理解しましょう。
解説者2人とも間違っていると思います。

投稿2026/04/26 09:25

hiroki-o

総合スコア1810

nanigasi

2026/04/27 12:20

詳細に解説くださりありがとうございます! 若干曖昧なニュアンスもある類の問題、、、としてあまり深入りしないように留意しつつ、学習を進めます。 迷っていたので本当に助かりました、 改めて、ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.25%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問