[模擬問題] PHP8上級 – 定義済みの変数(CTO古庄道明からの出題)

こんにちは。PHP技術者認定機構 CTOの古庄道明です。
今日もPHP8上級試験の模擬問題と解説を紹介します。
以下を解いて出題のイメージと知識を補っていただけると幸いです。

目次

問題

定義済みの変数 に関する説明の中で、誤っているものを1つ選びなさい。
なお、すべてのコードの先頭には下記のコードが書かれているものとする。

declare(strict_types=1);
error_reporting(-1);

選択肢

選択肢1
$_SERVER は、ヘッダ、パス、スクリプトの位置のような 情報を有する配列である。
この配列のエントリは Web サーバーにより生成されるため、PHP をコマンドラインで実行している場合には、使用できないものもある。
そのため、以下のコード

var_dump( $_SERVER['REMOTE_ADDR'] );

を Web サーバ経由で実行した場合は現在ページをみているユーザーの IP アドレスが出力されるが、コマンドラインから実行した場合は次のような結果となる。

Warning: Undefined array key "REMOTE_ADDR" in ...
NULL

選択肢2
$GLOBALS はグローバルスコープで使用可能なすべての変数への参照である。変数名が配列のキーとなる。そのため、以下のコード

function hoge() {
    var_dump( $GLOBALS['i'] );
}

$i = 999;
hoge();

は正しく実行でき、結果は次のとおりとなる。

int(999)

選択肢3
$argv はスクリプトに渡された引数の配列である。
(register_argc_argv が無効の場合は $argv は利用でき$argv[0] はスクリプトの実行に使う名前となり、$argv[1] 以降に引数の配列が入る。
そのため、

var_dump( $argv[1], $argv[2] );

上記のコードを

php sample.php aaa "bb cc dd" 999

のように呼び出すと、結果は次のとおりとなる。

string(3) "aaa"
string(8) "bb cc dd"

選択肢4
$_COOKIE は現在のスクリプトに HTTP クッキーから渡された変数の連想配列である。
Cookie から渡された値は $_COOKIE に入り、また $_COOKIE に設定した値は Cookieとして設定される。そのため、以下のコード

$_COOKIE['i'] = ($_COOKIE['i'] ?? 0) + 1;
var_dump($_COOKIE['i']);

をブラウザから呼び出すと、

1回目の結果は次のとおりとなる。

int(1)

2回目の結果は次のとおりとなる。

int(2)

3回目の結果は次のとおりとなる。

int(3)

回答と解説

問題は「定義済みの変数」についてです。
公式マニュアルの「定義済みの変数」のページを読んでおきましょう。
https://www.php.net/manual/ja/reserved.variables.php

選択肢1を見ていきましょう。
$_SERVER には、サーバー情報および実行時の環境情報が入っていて、この配列のエントリは、Web サーバーにより生成されます。
https://www.php.net/manual/ja/reserved.variables.server.php

この配列のエントリのうち、 REMOTE_ADDR は「現在ページをみているユーザーの IP アドレス」が入ります。
そのため、Webサーバ経由で実行された場合はユーザのIPアドレスが入りますが、コマンドラインから実行した場合は情報がないため、$_SERVER に REMOTE_ADDR のキーがそもそも存在しません。
そのため、PHP8における「その配列にキーがない状態でアクセスをした」場合の挙動である

  • Warning: Undefined array key “REMOTE_ADDR” in … が出る
  • null が返る
    となります。

したがってこの選択肢には正しいことが書かれています。

なお、実務において「ロードバランサやプロキシを経由」している場合は、注意が必要な時があります。
ロードバランサ等の設定によるのですが、REMOTE_ADDRが「ロードバランサのIPである」可能性があります。
その場合、これも設定によるのですが、「X-Forwarded-For」というヘッダのほうに「アクセスしてきたユーザのIPアドレスが入っている」事があるので、気をつけておくとよいでしょう。

選択肢2を見ていきましょう。
$GLOBALS は、グローバルスコープで使用可能なすべての変数への参照を含む連想配列です。
グローバルスコープの変数名が配列のキーとなります。
https://www.php.net/manual/ja/reserved.variables.globals.php

そのため、グローバルスコープに $i という変数がある場合、この変数は

$GLOBALS['i']

でアクセスが可能です。
故に、関数内での

var_dump( $GLOBALS['i'] );

のコードは、「グローバルスコープの $i をvar_dump()する」のと同じ意味合いになります。

したがってこの選択肢には正しいことが書かれています。

選択肢3を見ていきましょう。
$argv には、コマンドラインから実行したときに、現在のスクリプトに渡されたすべての引数の配列が含まれます。
また、[0]は「スクリプトの実行に使う名前(自身のファイル名)」が入るため、与えられた引数は $argv[1] 以降に入ってきます。
https://www.php.net/manual/ja/reserved.variables.argv.php

コマンドライン上で引数をどのように区切るかは、使用しているシェルなどの環境にも依存します。一般的なシェルでは、スペースを含む文字列をダブルクォートで囲むことで、1つの引数として渡すことができます。
そのため

php sample.php aaa "bb cc dd" 999

と呼んだ場合、$argvの中を表記すると、以下のようになります。

$argv = [
    0 => "sample.php",
    1 => "aaa",
    2 => "bb cc dd",
    3 => "999",
];

そのため

var_dump( $argv[1], $argv[2] );

であれば

string(3) "aaa"
string(8) "bb cc dd"

となります。

したがってこの選択肢には正しいことが書かれています。

選択肢4を見ていきましょう。
$_COOKIE は、現在のスクリプトに HTTP クッキーから渡された変数の連想配列です。
https://www.php.net/manual/ja/reserved.variables.cookies.php

HTTP クッキーは「key = value」の形をとるため、それがそのまま連想配列として $_COOKIE に入ってきます。
ただし、「$_COOKIE に設定した値は Cookie として設定され」ません。
Cookieの設定には、setcookie() や setrawcookie() などを使います。
https://www.php.net/manual/ja/function.setcookie.php
https://www.php.net/manual/ja/function.setrawcookie.php

そのため、例題のコードではCookieが設定できていないため、何度実行しても挙動としては

int(1)

が繰り返される動きになります。

したがってこの選択肢には誤りがあります。

選択肢4に誤りがあるため、解答は4になります。

PHP8上級試験と公式問題集に興味がある方は、以下のページをご覧のうえ、この機会に是非受験ください。

PHP8上級試験
https://www.phpexam.jp/summary/expert8

公式問題集:PHP8技術者認定上級試験公式問題集上巻
https://www.amazon.co.jp/dp/B0FQ1LTTQ4/

公式問題集:PHP8技術者認定上級試験公式問題集下巻ベータ
https://www.amazon.co.jp/dp/B0F7F4H8FP/

また、試験対策セミナーは毎月開催しています。興味がある方は以下のページをご覧いただき是非セミナーにもご参加ください。(フォローいただけるとセミナーのご案内が届くようになります)

PHP技術者認定機構の公式Peatixグループ
https://peatix.com/group/43424
www.phpexam.jp

この記事が気に入ったら
いいね または フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次