こんにちは。PHP技術者認定機構 CTOの古庄道明です。
今日もPHP8上級試験の模擬問題と解説を紹介します。
以下を解いて出題のイメージと知識を補っていただけると幸いです。
問題
SPL に関する説明の中で、誤っているものを1つ選びなさい。
なお、すべてのコードの先頭には下記のコードが書かれているものとする。
declare(strict_types=1);
error_reporting(-1);
選択肢
選択肢1
RecursiveDirectoryIterator クラスは、ファイルシステムのディレクトリを再帰的に反復処理するためのクラスである。
RecursiveDirectoryIterator クラスのオブジェクトを RecursiveIteratorIteratorクラスで処理することで、再帰的なイテレータを反復処理できるため、ファイルシステムのディレクトリを再帰的に反復処理する事が出来るようになる。
そのため、以下のコード
$dir = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(__DIR__)
);
while($dir->valid()) {
echo $dir->getPathname(), PHP_EOL;
$dir->next();
}
は正しく実行でき、次のような結果を得ることができる。
(ディレクトリ構成、ファイル名、出力順などは実行環境によって異なる)
/home/phpexam/phpexam/.
/home/phpexam/phpexam/..
/home/phpexam/phpexam/dir/.
/home/phpexam/phpexam/dir/..
/home/phpexam/phpexam/dir/test
/home/phpexam/phpexam/sample.php
選択肢2
SplFileInfo クラスは、ファイルの情報取得のためのクラスである。
単純にファイル名や拡張子の他、inode 番号や inode 変更時刻、ファイルの所有者など、様々な情報を得る事ができる。
そのため、以下のコード
$file_info = new SplFileInfo(__FILE__);
echo $file_info->getFilename(), PHP_EOL;
echo $file_info->getInode(), PHP_EOL;
echo $file_info->fread(9999), PHP_EOL;
を実行すると、結果は次のとおりとなる(i-node 番号は実行環境等によって変わる)。
sample.php
40318019
<?php
declare(strict_types=1);
error_reporting(-1);
$file_info = new SplFileInfo(__FILE__);
echo $file_info->getFilename(), PHP_EOL;
echo $file_info->getInode(), PHP_EOL;
echo $file_info->fread(9999), PHP_EOL;
選択肢3
SplFileObject クラスは、ファイルのためのオブジェクト指向のインターフェイスを提供する。
ファイルへの書き込みや読み込み、seek() メソッドでのファイルポインタの移動なども行うことができる。
そのため、以下のコード
$file = new SplFileObject(__FILE__);
while($line = $file->fgets()) {
echo $line;
}
echo 'fin';
を実行すると、結果は次のとおりとなる。
<?php
declare(strict_types=1);
error_reporting(-1);
$file = new SplFileObject(__FILE__);
while($line = $file->fgets()) {
echo $line;
}
echo 'fin';
fin
選択肢4
SplTempFileObject クラスは、一時ファイルのためのオブジェクト指向のインターフェイスを提供する。
一時ファイルは「メモリまたはテンポラリファイル」上に作成される。
そのため、以下のコード
$file = new SplTempFileObject();
echo $file->getPathname();
を実行すると
php://temp
となる。
回答と解説
問題は「SPL」についてです。
公式マニュアルの「SPL」のページを読んでおきましょう。
https://www.php.net/manual/ja/book.spl.php
選択肢1を見ていきましょう。
まず前提として DirectoryIterator クラスがあります。これは「ファイルシステムのディレクトリを閲覧する」ことが出来ます。
https://www.php.net/manual/ja/class.directoryiterator.php
class DirectoryIterator extends SplFileInfo implements SeekableIterator
となっており、SeekableIterator を実装しているため、foreachで処理をすることができます。
次に、設問にある RecursiveDirectoryIterator です。これは「ファイルシステムのディレクトリを再帰的に反復処理する」ことができます。
https://www.php.net/manual/ja/class.recursivedirectoryiterator.php
class RecursiveDirectoryIterator extends FilesystemIterator implements RecursiveIterator
再帰可能なイテレータとしての機能は RecursiveIterator が担っています。
https://www.php.net/manual/ja/class.recursiveiterator.php
interface RecursiveIterator extends Iterator
また、FilesystemIterator は、上述の DirectoryIterator を継承しています。
https://www.php.net/manual/ja/class.filesystemiterator.php
class FilesystemIterator extends DirectoryIterator
その為、RecursiveDirectoryIterator を RecursiveIteratorIterator で処理することで、「再帰的に」「ディレクトリを閲覧する」ことができます。
したがってこの選択肢には正しいことが書かれています。
選択肢2を見ていきましょう。
SplFileInfo クラスは、ファイルの情報取得のためのクラスになります。
Infoの名前の通り、様々な情報を得ることができます。
https://www.php.net/manual/ja/class.splfileinfo.php
一般的と思われる「ファイルのベース名を取得する」「ファイルへの絶対パスを取得する」「ファイルの拡張子を取得する」の他に、「ファイルサイズを取得する」「ファイルの所有者を取得する」や、「ファイルの inode を取得する」といったものもあります。
様々な「ファイルに対する情報」を得ることはできますが、一方で「ファイルの中身」に対するメソッドは持っていません。
そのため、選択肢のコードのうち、 fread() は実行することができません。
したがってこの選択肢には誤りがあります。
選択肢3を見ていきましょう。
SplFileObject クラスは、ファイルのためのオブジェクト指向のインターフェイスを提供します。
https://www.php.net/manual/ja/class.splfileobject.php
class SplFileObject extends SplFileInfo implements RecursiveIterator, SeekableIterator
SplFileObject は、SplFileInfoの機能に加えて、「ファイルの中身」に対する様々なメソッドを持っています。
その為、選択肢2にあったfread()や、fgets()などのメソッドも実装されています。
したがって、選択肢3のコードは、書かれている通りの動きをします。
この選択肢には正しいことが書かれています。
選択肢4を見ていきましょう。
SplTempFileObject クラスは、一時ファイルのためのオブジェクト指向のインターフェイスを提供します。
https://www.php.net/manual/ja/class.spltempfileobject.php
class SplTempFileObject extends SplFileObject
SplTempFileObject は php://temp を利用するため、「定義済みの上限まではメモリ上に、それを超えたらテンポラリファイル上に」ファイルのように扱うことのできる
領域を作成します。
https://www.php.net/manual/ja/wrappers.php.php#wrappers.php.memory
上述のため、$file->getPathname() を実行すると、 php://temp が得られます。
したがってこの選択肢には正しいことが書かれています。
選択肢2に誤りがあるため、解答は2になります。
PHP8上級試験と公式問題集に興味がある方は、以下のページをご覧のうえ、この機会に是非受験ください。
PHP8上級試験
https://www.phpexam.jp/summary/expert8
公式問題集:PHP8技術者認定上級試験公式問題集上巻
https://www.amazon.co.jp/dp/B0FQ1LTTQ4/
公式問題集:PHP8技術者認定上級試験公式問題集下巻ベータ
https://www.amazon.co.jp/dp/B0F7F4H8FP/
また、試験対策セミナーは毎月開催しています。興味がある方は以下のページをご覧いただき是非セミナーにもご参加ください。(フォローいただけるとセミナーのご案内が届くようになります)
PHP技術者認定機構の公式Peatixグループ
https://peatix.com/group/43424
www.phpexam.jp

