プログラミング

プログラミング初心者のPHP修羅の道#12〜PHP8上級問題を徹底追求する〜

PHP8上級資格取得へ向けたアウトプット記事になります。

PHP試験運営団体より公開されている模擬試験を1つ1つみていく形で事細かくみていきますが、勉強途中ゆえ間違っている部分に関してはご了承ください。

PHP上級資格のメイン教材はPHPマニュアルと指定されていますので、このマニュアルを主に踏襲した内容となっています。

主な勉強教材は以下になります。

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クラスはこのストリームを使用して一時ファイルを作成し、ファイルアクセスを提供しています。

つまり、一時的にファイルを使用する必要がある場合に、ファイルを実際に作成することなくメモリ上で操作ができるようになるということになります。

よって、この選択肢は合っています。

ABOUT ME
ヒロ
社会人4年目/25歳/食品商社で2年間営業した後、IT業界にシステムエンジニアとして転職/Java,PHP言語を扱う開発エンジニア