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

PHP初級レベルから脱却して中級/上級レベルにいきたい人にピッタリの内容ですね。
PRIME STUDY認定模擬問題のリンクはこちらです → https://study.prime-strategy.co.jp/
問題文
関数 に関する説明の中で、誤っているものを1つ選びなさい。
なお「\」はバックスラッシュに読み替えること。
また、すべてのコードには下記のコードが適切な箇所に書かれているものとする。
declare(strict_types=1);
error_reporting(-1);
下記はマニュアルから一部引用した内容である。
stream_wrapper_register ( string $protocol , string $class , int $flags = 0 ) : bool
成功した場合に true を、失敗した場合に false を返します。
stream_wrapper_register() は、 protocol というハンドラが既にある場合、 false を返します。
stream_filter_prepend ( resource $stream , string $filtername , int $read_write = ? , mixed $params = ? ) : resource
(1)
PHP では「ファイル、ネットワーク、データ圧縮などに関する、 共通した一連の関数群と利用法を持つ操作の一般化の手法」として、ストリームがある。
また「ストリームにおいてどのように特定の プロトコル/エンコーディングを扱うかを扱うかを指示する付加的なコード」をラッパーと呼称する。
PHP において、組み込みのラッパーは様々にあるが、例えば php:// はさまざまな入出力ストリームへのアクセスを提供している。
例えば php://input は読み込み専用のストリームで、リクエストの body 部から生のデータを読み込むことができる。
そのため、以下のコード
var_dump( file_get_contents('php://input') );
を
curl https://www.example.com/stream.php -d '{"exam_num":100,"exam_string":"value"}'
の形で呼び出すと、結果は次のとおりとなる。
string(38) "{"exam_num":100,"exam_string":"value"}"
(2)
php://memory および php://temp は読み書き可能なストリームで、一時データをファイルのように保存できるラッパーである。
そのため、以下のコード
$csv_string = "1,2,3\n4,5,6\n";
$fp = fopen('php://memory', 'r+');
fwrite($fp, $csv_string);
fseek($fp, 0, SEEK_SET);
while($row = fgetcsv($fp)) {
var_dump($row);
}
を実行すると、結果は次のとおりとなる。
array(3) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
[2]=>
string(1) "3"
}
array(3) {
[0]=>
string(1) "4"
[1]=>
string(1) "5"
[2]=>
string(1) "6"
}
(3)
stream_wrapper_register() 関数を使うと、新しいラッパーとその挙動を登録する事ができる。
そのため、以下のコード
$r = stream_wrapper_register('dummy', 'PhpStreamDummy');
var_dump($r);
を実行すると、結果は次のとおりとなる。
Warning: stream_wrapper_register(): class 'PhpStreamDummy' is undefined in …
bool(false)
一方で以下のコード
class PhpStream {
}
$r = stream_wrapper_register('php', 'PhpStream');
var_dump($r);
を実行すると、結果は次のとおりとなる。
bool(true)
(4)
stream_filter_prepend() 関数を使うと、フィルタをストリームに付加する事ができる。
そのため、exam.txt ファイルに「文字コード sjis で書かれた文字」を入れた上で、以下のコード
$file_name = './exam.txt';
$fp = fopen($file_name, 'r');
var_dump( fgets($fp) );
fclose($fp);
$fp = fopen($file_name, 'r');
$fp2 = stream_filter_prepend($fp, 'convert.iconv.SJIS-win/UTF-8');
var_dump( fgets($fp) );
fclose($fp);
を実行すると、結果は次のとおりとなる。
string(17) "sjis?????????
"
string(23) "sjisでこんにちは
"
解説
選択肢1の解説
正しいです。
php://input はリクエストボディのデータを読み取るためのストリームで、HTTPリクエストの生データを取得するために使われます。
選択肢2の解説
正しいです。
php://memory および php://temp は、メモリ内や一時ファイルにデータを保存するためのストリームラッパーで、fwrite() と fseek() を使ってデータを操作し、fgetcsv() で CSV データを処理できます。
選択肢3の解説
誤りです。stream_wrapper_register() に登録するクラスが適切に実装されていないと、false が返されるため、bool(true) とする記述は誤りです。
選択肢4の解説
正しいです。
stream_filter_prepend() は、指定したストリームにフィルタを追加します。文字コードの変換フィルタを使うことで、sjis から UTF-8 へ変換される例が適切に動作します。
正解選択肢
以上より選択肢3が正解となります。
コメント