PHP8上級資格取得へ向けたアウトプット記事になります。
PHP試験運営団体より公開されている模擬試験を1つ1つみていく形で事細かくみていきますが、勉強途中ゆえ間違っている部分に関してはご了承ください。
PHP上級資格のメイン教材はPHPマニュアルと指定されていますので、このマニュアルを主に踏襲した内容となっています。
試験問題1-2 | 模擬試験を解く#1 |
---|---|
試験問題3 | 模擬試験を解く#2 |
試験問題4 | 模擬試験を解く#3 |
試験問題5 | 模擬試験を解く#4 |
試験問題6 | 模擬試験を解く#5 |
試験問題7 | 模擬試験を解く#6 |
試験問題8 | 模擬試験を解く#7 |
試験問題9 | 模擬試験を解く#8 |
本記事 | 模擬試験を解く#9 |
主な勉強教材は以下になります。
1.独習PHP第4版
2.はじめてのPHP
3.PHP公式マニュアル
PHP8上級試験模擬問題
試験問題10
SPLに関する説明の中で、誤っているものを1つ選びなさい。
なお、すべてのコードの先頭には下記のコードが書かれているものとする。
declare(strict_types=1);
error_reporting(-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
まずは、問題文にあるSPLについて触れていきます。
SPL(Standard PHP Library)
SPLは、標準的な問題を解決するためのインターフェイスやクラスを集めたものです。
標準データ構造や、オブジェクトを走査するためのイテレータ、インターフェイス、標準の例外、そしてファイルを扱うクラスなどを提供しています。
次に、選択肢を見ていきます。
PHPのRecursiveDirectoryIteratorクラスは、再帰的にディレクトリ内のファイルを走査するためのクラスです。
このクラスを使用することで、指定されたディレクトリ内のすべてのファイルとディレクトリを取得することができます。また、RecursiveDirectoryIteratorクラスは、IteratorIteratorクラスを実装しており、foreachループで反復処理することができます。
$dir = new RecursiveDirectoryIterator('/path/to/dir');
$iterator = new RecursiveIteratorIterator($dir);
foreach ($iterator as $file) {
echo $file->getPathname() . "\n";
}
上記は選択肢のソースと同じような処理ですが、よりわかりやすく記述したソースになります。
この例では、指定されたディレクトリ/path/to/dir
内のすべてのファイルとディレクトリを取得し、それぞれのファイルパスを出力しています。
RecursiveDirectoryIteratorクラスは、コンストラクタに引数を渡すことで、検索するディレクトリの設定などができます。
また、RecursiveDirectoryIteratorクラスは、RecursiveIteratorIteratorクラスを使用して、ディレクトリ内の要素を反復処理することができます。
・RecursiveIteratorIterator::valid()
現在の位置が有効かどうかをチェックします。
・DirectoryIterator::getPathname()
現在のファイルのパスとファイル名を返します。
・RecursiveDirectoryIterator::next()
次のエントリ(プログラムの開始地点)に移動します。
よって、この選択肢は合っています。
選択肢②
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;
まずは選択肢文についてみていきます。
inode番号とは
ファイルシステムにおいてファイルやディレクトリを一意に識別するための番号で、ファイル名やパス名などの変更や移動があってもinode番号は変化しません。
inode番号はstat()関数を使用することで以下のように取得することができます。
$filename = '/path/to/file';
$stat = stat($filename);
$inode = $stat['ino'];
inode時刻とは
ファイルシステムにおいてファイルやディレクトリの最終更新時刻を表す情報のことを指し、inode時刻には、最終アクセス時刻、最終更新時刻、最終変更時刻の3つがあります。
inode時刻はstat()関数を使用することで以下のように取得することができます。
$filename = '/path/to/file';
$stat = stat($filename);
$atime = $stat['atime']; // 最終アクセス時刻
$mtime = $stat['mtime']; // 最終更新時刻
$ctime = $stat['ctime']; // 最終変更時刻
SplFileInfoクラスは、ファイルやディレクトリに関する情報を提供するためのクラスでPHPの標準ライブラリであるSPLに含まれています。
ファイルやディレクトリの存在確認や属性情報の取得、パーミッションの変更などさまざまなファイル操作を行うことができますが、ファイルの内容を読み込むことはできません。
選択肢のコードではfread()メソッドによってファイルの内容を読み込もうとしているためエラーが発生します。
よって、この選択肢は誤りです。
選択肢③
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
$file = new SplFileObject(__FILE__);
1行目で現在実行中のPHPファイルを指定してファイルオブジェクトを作成しています。
このオブジェクトを使用することでファイルの内容を読み込むことができるようになります。
while($line = $file->fgets()) {
echo $line;
}
echo 'fin';
次に、SplFileObjectクラスのfgets()メソッドを使用して、ファイルから1行ずつ読み込み、読み込んだ行をechoで出力しています。
ファイルの終端に到達すると、ループから抜けます。
ループから抜けたタイミングで最後にfinという文字を出力するため、この選択肢は合っています。
SplFileObjectクラスのfgets()メソッドは、ファイルの終端に到達するまで1行ずつ読み込みます。
そのため、非常に大きなファイルの場合はメモリ使用量が大きくなる可能性があるので、適切にメモリを制御する必要があります。
選択肢④
SplTempFileObject
クラスは、一時ファイルのためのオブジェクト指向のインターフェイスを提供する。
一時ファイルは「メモリまたはテンポラリファイル」上に作成される。
そのため、以下のコード
$file = new SplTempFileObject();
echo $file->getPathname();
を実行すると php://temp
となる。
SplTempFileObject
クラスは、一時ファイルを扱うためのオブジェクト指向のインターフェースを提供するクラスです。
一時ファイルとは、一時的にデータを保存するために使用され、不要になった後に自動的に削除されるファイルのことを指します。
SplTempFileObject
クラスのインスタンスを作成すると、一時ファイルがメモリまたはテンポラリファイル上に作成され、この一時ファイルに対してファイルアクセスを行うことができます。
選択肢のコードを実行すると、php://temp
という文字列が出力されますが、これはSplTempFileObject
クラスが作成した一時ファイルが、PHPのphp://temp
ストリーム上にあることを表しています。
php://temp
は、一時的にファイルデータを格納するためのメモリバッファーを提供するストリームで、SplTempFileObject
クラスはこのストリームを使用して一時ファイルを作成し、ファイルアクセスを提供しています。
つまり、一時的にファイルを使用する必要がある場合に、ファイルを実際に作成することなくメモリ上で操作ができるようになるということになります。
よって、この選択肢は合っています。