
PHP8 上級/準上級試験の認定模擬問題として、プライム・ストラテジー様のPRIME STUDYが認定されているようです。ただ、この模擬問題には解説がありませんので解説をまとめていこうと思います。シリーズ第10回目です。

PHP初級レベルから脱却して中級/上級レベルにいきたい人にピッタリの内容ですね。
PRIME STUDY認定模擬問題のリンクはこちらです → https://study.prime-strategy.co.jp/
問題文
SPL に関する説明の中で、誤っているものを1つ選びなさい。
なお、すべてのコードの先頭には下記のコードが書かれているものとする。
declare(strict_types=1);
error_reporting(-1);
(1)
RecursiveDirectoryIterator クラスは、ファイルシステムのディレクトリを再帰的に反復処理するためのクラスである。
RecursiveDirectoryIterator クラスのオブジェクトをRecursiveIteratorIterator クラスで処理する事によって、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 変更時刻、ファイルの所有者など、様々な情報を得る事ができるほか、SplFileObject クラスと同様のファイル操作も行う事ができる。
そのため、以下のコード
$file_info = new SplFileInfo(FILE);
echo $file_info->getFilename(), PHP_EOL;
echo $file_info->getInode(), PHP_EOL;
echo $file_info->fread(9999), PHP_EOL;
を実行すると、結果は次のとおりとなる。
sample.php
40318019
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';
を実行すると、結果は次のとおりとなる。
$file = new SplFileObject(FILE);
while($line = $file->fgets()) {
echo $line;
}
echo 'fin';
fin
(4)
SplTempFileObject クラスは、一時ファイルのためのオブジェクト指向のインターフェイスを提供する。
一時ファイルは「メモリまたはテンポラリファイル」上に作成される。
そのため、以下のコード
$file = new SplTempFileObject();
echo $file->getPathname();
を実行すると
php://temp
となる。
解説
選択肢1の解説
正しいです。
RecursiveDirectoryIterator と RecursiveIteratorIterator を組み合わせることで、ディレクトリ内のファイルを再帰的に処理できます。指定されたコードも適切に動作します。
RecursiveDirectoryIterator クラスは、指定したディレクトリ内のファイルやサブディレクトリを再帰的に処理するためのクラスです。通常の DirectoryIterator は指定したディレクトリの直下のファイルやフォルダしか取得できませんが、RecursiveDirectoryIterator を使うと、サブディレクトリの中も含めて処理できます。
RecursiveIteratorIterator は、RecursiveDirectoryIterator などの「再帰的なイテレータ」を処理するためのクラスです。通常、イテレータは「一つのリスト(配列など)を順番に処理する」ための仕組みですが、RecursiveIteratorIterator を使うと「再帰的なイテレータ(入れ子になったデータ構造)」も簡単に処理できます。
コードを見ていきましょう。
(1~3行目)RecursiveDirectoryIterator に DIR(ディレクトリ)を指定し、その結果を RecursiveIteratorIterator に渡しています。具体的にいうと、「new RecursiveDirectoryIterator(DIR)」で 指定したディレクトリ DIR の中を再帰的に取得するイテレータを作成しています。「new RecursiveIteratorIterator(…)」でそのイテレータをさらに処理できるようにしています。
(5~8行目)valid() で現在の要素が有効かをチェック(ファイルやディレクトリがあるかどうか)、getPathname() でファイルやディレクトリのフルパスを取得、next() で次の要素へ進むという流れです。
問題文にあるファイルやディレクトリ構成は以下のようなものだと予想されます。
/home/phpexam/phpexam/
├── dir/
│ ├── test
├── sample.php
この結果、問題文のような結果が得られますが、dir/test や sample.php のパスが取得できることに加え、.(カレントディレクトリ)と ..(親ディレクトリ)も結果に含まれるところがポイントです。
選択肢2の解説
誤っています。
SplFileInfo クラスはファイルの情報を取得するためのクラスですが、SplFileInfo クラス自体にはファイルを読み込むためのメソッドは含まれていません。したがって、fread メソッドを使用しようとするとエラーが発生します。SplFileInfo クラスはファイルに関するメタ情報(例:ファイル名、パス、inode 番号など)を取得するためのもので、ファイルの内容を読み書きする機能はありません。
ファイルを読み込むためには、SplFileObject クラスを使用する必要があります。SplFileObject はファイル操作を行うためのクラスです。
選択肢3の解説
正しいです。
SplFileObject クラスはファイルの読み書きやファイルポインタの操作を行うためのクラスです。PHPの標準ライブラリ(SPL)に含まれているクラスで、ファイルの読み書きをオブジェクト指向で扱うためのクラスです。
従来、fopen()、fread()、fwrite() などの関数を使ってファイルを操作していましたが、
SplFileObject を使うと オブジェクトを通じて、簡単にファイルを操作できる ようになります。
問題文のコードにあるfgets()は1行ずつ読み込むものですが、この他にfwrite() で書き込み や seek() を使ってファイルポインタの移動も可能です。
選択肢4の解説
正しいです。
SplTempFileObject クラスは、PHPの標準ライブラリ(SPL)に含まれているクラスで、「一時ファイル」を作成して操作するためのクラス です。
一時ファイルとは、プログラムが実行中の間だけ存在するファイル のことで、メモリ上 や 一時フォルダ に作られるので、プログラム終了後に自動で削除 されます。ファイルの一時的な保存やデータ処理等に使います。
一時ファイルは php://temp という仮想パスに作成されますので、getPathname() を呼び出すと、SplTempFileObject のパス「php://temp」が取得できます。
php://temp は、PHPが用意した特別なストリーム で、一時ファイルを扱うために使われるものです。
正解選択肢
以上より選択肢2が正解となります。
コメント