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

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

今回はPHPの配列操作関数に関する問題です。array_map()、array_filter()、array_walk() などの関数の挙動や使いどころについての理解が問われます。実務でも頻繁に使用されますのでしっかりと押さえておきましょう!
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が正解となります。
他の問題へ
模擬問題(1)インストール
模擬問題(2)変数の型
模擬問題(3)クラス
模擬問題(4)メソッドその1
模擬問題(5)メソッドその2
模擬問題(6)リファレンス
模擬問題(7)名前空間
模擬問題(8)エラー
模擬問題(9)定義済みのインターフェイスとクラスおよび SPL インターフェイス
模擬問題(10)SPL
模擬問題(11)定義済の変数
模擬問題(12)PHP7.0.xからPHP7.1.xへの移行
模擬問題(13)可変変数
模擬問題(14)PHP7.3.xからPHP7.4.xへの移行
模擬問題(15)PHP7.4.xからPHP8.0.xへの移行
模擬問題(16)制御構造
模擬問題(17)XSS(クロスサイトスクリプティング)
模擬問題(18)ファイルアップロード
模擬問題(19)推測困難なトークン
模擬問題(20)セッション
模擬問題(21)PHP のメモリ消費
模擬問題(22)関数その1
模擬問題(23)関数その2
模擬問題(24)関数その3
模擬問題(25)関数その4
模擬問題(26)関数その5
模擬問題(27)関数その6
模擬問題(28)関数その7
模擬問題(29)関数その8
模擬問題(30)関数その9
コメント