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

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

今回はPHPのストリーム処理に関する問題です。ストリームは、ファイル操作やネットワーク通信、データ圧縮など、さまざまな入出力処理において重要な概念です。この問題では、ストリームラッパーやフィルタの使用方法、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が正解となります。
他の問題へ
模擬問題(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
コメント