• PHP
【php8上級/準上級試験】模擬問題解説 問題20. $_SESSION

「第1回 PHP 8 上級 模擬試験」を解説していきます

本記事ではひたすら下記記事の模擬試験の解説をしていきたいと思います!

第1回 PHP 8 上級 模擬試験
https://study.prime-strategy.co.jp/study/ph8ex1/

解説記事一覧

模擬問題 20

セッション に関する説明の中で、誤っているものを1つ選びなさい。
また、すべてのコードには下記のコードが適切な箇所に書かれているものとする。

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

session_save_path ( string|null $path = null ) : string|false
session_save_path() は、 現在のセッションデータ保存パスを返します。

session_set_cookie_params ( int $lifetime_or_options , string|null $path = null , string|null $domain = null , bool|null $secure = null , bool|null $httponly = null ) : bool
session_set_cookie_params ( array $lifetime_or_options ) : bool
session_set_save_handler ( callable $open , callable $close , callable $read , callable $write , callable $destroy , callable $gc , callable $create_sid = ? , callable $validate_sid = ? , callable $update_timestamp = ? ) : bool
session_set_save_handler ( object $sessionhandler , bool $register_shutdown = true ) : bool

PHP は「複数回のアクセスを通じて特定のデータを保持する手段」としてのセッションサポート機能を持っている。

セッションサポート機能により、スーパーグローバル配列 $_SESSION を使ってリクエスト間でデータを格納できるようになる。

そのため、以下のコード

ession_start();
$_SESSION['key'] = 'value';

をブラウザ経由で実行した後に以下のコード

session_start();
var_dump($_SESSION['key']);
をブラウザ経由で実行すると、結果は次のとおりとなる。

string(5) "value"

  1. session_start() を呼び出す
  • PHP は session_start() を実行すると、セッションを開始する。
  • セッション ID (PHPSESSID) がセットされる。(クッキー or URLパラメータ)
  • すでに有効なセッションがある場合、そのセッションのデータを $_SESSION に復元する。
  1. $_SESSION を使ってデータを格納
  • $_SESSION['key'] = 'value'; のようにデータを保存すると、サーバー側のセッションストレージに保存される。
  1. リクエストをまたいでデータを利用
  • session_start() を再び実行すると、サーバー上のセッションデータが $_SESSION に復元される。
PHPセッションの仕組み クライアント側 サーバー側 1 session_start() セッション開始・復元 セッションID (PHPSESSID) Cookie または URL 2 $_SESSION[‘key’] = ‘value’; データをセッションに格納 セッション ストレージ 3 次回リクエスト時 セッションIDを送信 セッションID送信 $_SESSIONにデータ復元

問題文の内容は正しい⭕です

PHP のセッションサポート機能において、セッションデータはデフォルトではファイルに保存される。

また、保存先のファイルは session_save_path() 関数によって取得または設定する事ができる。

そのため、以下のコード

ob_start();
var_dump( session_save_path() );
session_save_path('/tmp');
var_dump( session_save_path() );

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

string(0) “”
string(4) “/tmp”

この説明に誤りはありません。内容は⭕です

PHP のセッションサポート機能において、セッション ID というセッション ID と呼ばれるユニークな ID が割り当てられ、それは基本的にユーザー側にクッキーとして保存される。

そのためクッキーを使うので、セッション ID を保存するクッキーに対するパラメータを設定する事ができる関数が存在する。

そのため、以下のコード

ob_start();
var_dump( session_get_cookie_params() );
session_set_cookie_params(['lifetime' => 86400, 'samesite' => 'Strict', 'secure' => true, 'httponly' => true]);
var_dump( session_get_cookie_params() );

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

array(6) {
  ["lifetime"]=>
  int(0)
  ["path"]=>
  string(1) "/"
  ["domain"]=>
  string(0) ""
  ["secure"]=>
  bool(false)
  ["httponly"]=>
  bool(false)
  ["samesite"]=>
  string(0) ""
}
Warning: session_set_cookie_params(): Unrecognized key 'samesite' found in the options array in ...
array(6) {
  ["lifetime"]=>
  int(86400)
  ["path"]=>
  string(1) "/"
  ["domain"]=>
  string(0) ""
  ["secure"]=>
  bool(true)
  ["httponly"]=>
  bool(true)
  ["samesite"]=>
  string(0) ""
}

PHP 7.3以降ではsamesiteオプションは正しく認識されます。

PHPバージョンごとのセッションCookieパラメータ PHP 7.2以前 session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly); • samesiteオプションなし • 引数による個別指定 PHP 7.3以降 session_set_cookie_params([ ‘lifetime’ => 86400, ‘samesite’ => ‘Strict’, // 正しく認識される ‘secure’ => true, ‘httponly’ => true]); PHP 7.3以降での出力 ‘samesite’ => ‘Strict’ // 正しく設定される Warning は発生しない

よって問題文は誤り❌です

PHP のセッションサポート機能において、セッションデータはデフォルトではファイルに保存される。

しかし「ファイル以外 (DB 等)」に保存をする事も出来る。そのためにsession_set_save_handler() という関数がある。

最近は後者の方法で実装される事が多いが、その場合、SessionHandlerInterface、 SessionIdInterface (オプション) または SessionUpdateTimestampHandlerInterface を実装したクラス を継承したクラスのオブジェクトを引数として指定する必要がある。

そのため、以下のコード

class Hoge {
}

ob_start();
session_set_save_handler(new Hoge);

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

Fatal error: Uncaught TypeError: session_set_save_handler(): Argument #1 ($open) must be of type SessionHandlerInterface, Hoge given in …

よって選択肢の内容は正しい⭕です

問題番号正解の選択肢
1PHPの「最新以外の(古い)コード」は、公式サイトでの提供は全くしていない。そのため、古いバージョンのコードが必要な場合、別途「非公式の外部サイト」からソースコードを入手する必要がある。
2論理型 (boolean) は「真偽値」とも呼ばれ、値は true か false か null のいずれかになる。なお、true、false、null の文字は、大文字でも小文字でもよい。
3抽象クラスから継承する際、親クラスで abstract としてマークされた全てのメソッドは子クラスで定義する必要があり、可視性は同等(またはより緩い制約)で、必須引数の数は同じであれば型宣言が異なってもかまわない。
4PHP において、デストラクタは __destruct() メソッドで実装される。親クラスのデストラクタは暗黙的に呼ばれ、呼び出し順序は「子クラスのデストラクタ → 親クラスのデストラクタ」となる。
5__get() はアクセス不能(protected または private)または存在しないプロパティからデータを読み込む際に使用される。なお、__getStatic() は存在せず、オブジェクトや静的コンテキストで動作しない。
6PHP のリファレンス渡しを使用すると、関数内で引数を修正できる。(※※正解テキストでは「呼び出す側で変数に & を付ける必要がある」と記載されています。)
7名前空間は namespace キーワードで宣言する。通常はファイルの先頭に記述する必要があり、名前空間宣言前に書かれたクラスはその名前空間に含まれない。
8PHP 5 では Exception クラスが全例外の基底クラスだったが、PHP 7 以降は Exception クラスは Throwable インタフェースを基底とし、Error クラスが内部エラーの基底クラスとして導入された。
9ArrayAccess インターフェイスは、オブジェクトを配列としてアクセスするための機能を提供する。
10SplFileInfo クラスは、ファイルの情報取得や操作を行うためのクラスである。
11$_COOKIE は、HTTP クッキーから渡された値が連想配列として格納され、また設定も可能である。
12PHP 7.1.x では、文字列操作関数で負のオフセット指定が可能となり、[] や {} による文字単位のアクセスも文字列の末尾からのオフセットとして解釈される。
13可変変数は、スーパーグローバル変数にも使用できる。
14PHP 7.4.x では、波括弧を使った配列や文字列のオフセットアクセスの文法は非推奨となった。
15PHP 8 では、private メソッドの継承に関するルールが変更され、親クラスの同名メソッドの可視性に関係なく子クラスでオーバーライド可能となった。
16break は、現在実行中の for, foreach, while, do-while, switch 構造の実行を終了し、オプションでネストしたループの何段分を抜けるか指定できる。
17XSS 対策として、htmlentities() を適切に使用することで、文字列や配列の入力に対して安全な出力が可能となる。
18アップロードされたファイルの元のファイル名は、$_FILES[‘{formのnameの値}’][‘name’] に格納され、move_uploaded_file() の第二引数として利用できる。
19uniqid() と mt_rand() を組み合わせることで、暗号論的にランダムな(推測困難な)トークンを生成できる。
20PHP のセッションでは、セッション ID がクッキーに保存され、session_set_cookie_params() によりそのクッキーのパラメータを設定できる。
21PHP の変数の参照カウントは、xdebug_debug_zval() で確認でき、オブジェクトを clone した場合は内部的に参照が使われ、一時的に参照カウントが増加する。
22DirectoryIterator クラスは、ディレクトリ内のファイルやサブディレクトリの情報を取得するシンプルなインターフェイスを提供する。
23mail() 関数は、メールを送信するための関数で、第四引数で追加のヘッダー情報を指定できる。
24escapeshellarg() と escapeshellcmd() は、外部入力をシェルコマンドの引数として使用する際に必要なエスケープ処理を行い、どちらを使用しても意味合いは同じである。
25stream_wrapper_register() 関数を使用すると、新しいストリームラッパー(プロトコルハンドラ)を登録できるが、既に存在する場合は失敗する。
26strpos() 関数は、文字列内で指定した部分文字列の最初の出現位置を返し、見つからなければ false を返す。ただし、先頭位置の場合は 0 が返るため注意が必要。
27Phar のスタブには __HALT_COMPILER() が使用され、これ以降のコードはコンパイルされない。
28function_exists() 関数は、指定された関数が定義されているかどうかをチェックし、存在すれば true を返す。
29openssl_decrypt() 関数は、openssl_encrypt() で暗号化されたデータを正しく復号し、元のデータを取り戻す。
30strtotime() 関数は、英語形式の日付文字列を Unix タイムスタンプに変換し、無効な日付の場合は false を返す。