【やさしく解説】PHP8上級試験の模擬問題(22)

PHP
スポンサーリンク

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

PHP初級レベルから脱却して中級/上級レベルにいきたい人にピッタリの内容ですね。

PRIME STUDY認定模擬問題のリンクはこちらです → https://study.prime-strategy.co.jp/ 

問題文

関数 に関する説明の中で、誤っているものを1つ選びなさい。
なお「\」はバックスラッシュに読み替えること。
また、すべてのコードには下記のコードが適切な箇所に書かれているものとする。

declare(strict_types=1);
error_reporting(-1);
下記はマニュアルから一部引用した内容である。

Directory クラスのインスタンスを作るには dir() 関
数を使います。new 演算子は使いません。

chdir ( string $directory ) : bool
getcwd ( ) : string

DirectoryIterator extends SplFileInfo implements SeekableIterator {
public DirectoryIterator::__construct ( string $path )

RecursiveDirectoryIterator extends FilesystemIterator implements SeekableIterator , RecursiveIterator {

RecursiveIteratorIterator implements OuterIterator {
public RecursiveIteratorIterator::__construct ( Traversable $iterator , int $mode = RecursiveIteratorIterator::LEAVES_ONLY , int $flags = 0 )

SeekableIterator extends Iterator {
RecursiveIterator extends Iterator {
Iterator extends Traversable {

(1)
Directory クラスは、ディレクトリ内を走査するためのクラスである。

そのため、以下のコード

$dir_obj = dir(DIR);
var_dump($dir_obj);

while (false !== ($entry = $dir_obj->read())) {
  echo $entry, PHP_EOL;
}
$dir_obj->close();


を実行すると、結果は次のとおりとなる。

object(Directory)#1 (2) {
  ["path"]=>
  string(10) "/home/php_exam"
  ["handle"]=>
  resource(5) of type (stream)
}
.
..
.cache
.config
(以下略)

(2)
chdir() 関数はカレントディレクトリを変更する。また getcwd() 関数はカレントのワーキングディレクトリを取得する。

そのため、以下のコード

var_dump(getcwd());
chdir('../');
var_dump(getcwd());


を実行すると、結果は次のとおりとなる。

string(14) "/home/php_exam"
string(5) "/home"

(3)
DirectoryIterator クラスは、ファイルシステムのディレクトリを閲覧するためのシンプルなインターフェイスを提供する。

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

また DirectoryIterator が SplFileInfo を継承しているため、ファイルの情報に纏わるメソッドなどを一通り使う事ができる。

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

そのため、以下のコード

// 現在のディレクトリを走査
foreach (new DirectoryIterator(DIR) as $file) {
  if($file->isDot()) {
    continue;
  }

  echo $file, PHP_EOL;

  if ($file->isDir()) {
    // DirectoryIteratorのインスタンスを使って1階層深いディレクトリを走査
    foreach (new DirectoryIterator($file) as $file2) {
        if($file2->isDot()) continue;
        echo "\t{$file2}", PHP_EOL;;
    }
  }
}


を実行すると

.cache
.config
.bashrc
Beginner
sample
src
Advanced
sample
src
(以下略)


のような表記となり、ディレクトリ階層を 1 段深くまで処理する事ができる。

(4)
RecursiveDirectoryIterator は、ファイルシステムのディレクトリを再帰的に反復処理するためのインターフェイスである。

ただしこのクラス単体では再帰的な反復処理はできず、RecursiveIteratorIterator クラスを合わせて使う必要がある。

そのため、以下のコード

$directorys = new \RecursiveDirectoryIterator(DIR);
$iterator = new \RecursiveIteratorIterator($directorys);
foreach($iterator as $file) {
  echo $file, PHP_EOL;
}


を実行すると

/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
(以下略)


のような表記となり、再帰的にファイルを処理する事ができる。

解説

選択肢1の解説

正しいです。
dir() 関数で取得した Directory クラスのインスタンスを使用してディレクトリ内のファイルを走査するコードは、期待通りに動作します。read() メソッドでエントリを読み込み、close() でストリームを閉じる処理が行われています。

選択肢2の解説

正しいです。
chdir() 関数でカレントディレクトリを変更し、getcwd() で変更後のカレントディレクトリを取得する動作は正しいです。実行後の結果も説明通りです。

選択肢3の解説

誤りです。
DirectoryIterator クラスは SeekableIterator を実装していないため、この部分が誤りです。

選択肢4の解説

正しいです。
RecursiveDirectoryIterator と RecursiveIteratorIterator を組み合わせて、再帰的にディレクトリを走査するコードは、説明通りに動作します。再帰的にディレクトリを処理するために RecursiveIteratorIterator を使う必要があることも正しいです。

正解選択肢

以上より選択肢3が正解となります。

コメント

タイトルとURLをコピーしました