プログラミング

プログラミング初心者のPHP修羅の道#13〜PHP8上級問題を徹底追求する〜

この記事のキーワード

$_SERVER$GROVALS$argv$_COOKIEセッションsetcookie()関数

PHP8上級資格取得へ向けたアウトプット記事になります。

PHP試験運営団体より公開されている模擬試験を1つ1つみていく形で事細かくみていきますが、勉強途中ゆえ間違っている部分に関してはご了承ください。

PHP上級資格のメイン教材はPHPマニュアルと指定されていますので、このマニュアルを主に踏襲した内容となっています。

主な勉強教材は以下になります。

1.独習PHP第4版

2.はじめてのPHP

 

3.PHP公式マニュアル

 

PHP8上級試験模擬問題

試験問題11

 

定義済の変数 に関する説明の中で、誤っているものを1つ選びなさい。
なお「¥」はバックスラッシュに読み替えること。

 

選択肢①

 

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

declare(strict_types=1);
error_reporting(−1);
var_dump($_SERVER['REMOTE_ADDR'] );

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

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

となる。

 

$_SERVER配列は、Webサーバーから提供される情報を含むグローバル変数であり、ヘッダ、パス、スクリプトの位置、クライアントのIPアドレスなど、さまざまな情報が含まれます。

選択肢のコードで使用されている$_SERVER[‘REMOTE_ADDR’]は、クライアントのIPアドレスを表すエントリであり、Webサーバーを介して実行された場合には正しく動作します。

しかし、コマンドラインから実行された場合、このエントリが定義されていないため、警告メッセージが出力され、NULLが返されます

PHPをコマンドラインから実行している場合、これらの情報はサーバーから提供されないため、サーバ変数のほとんどは利用できないか、なんの意味も持たないことがあります。

ちなみに、エントリとは配列内の個々の要素を指す用語です。

たとえば、$_SERVER配列には、Webサーバーから提供される情報が含まれており、各エントリには特定の情報が格納されています。

選択肢にある$_SERVER[‘REMOTE_ADDR’]エントリには、クライアントのIPアドレスが格納されています。

以上より、選択肢は合っています。

 

選択肢②

 

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

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

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

$i = 999;
hoge();

は正しく実行でき、結果は

int(999)

となる。

 

GROBALSについて深掘っていきます。

GROBALSとglobalの違い

GROBALSglobalは共にグローバル変数を扱うためのキーワード

GROBALS

現在PHPスクリプト内のグローバルスコープに定義されているすべての変数への参照を含む連想配列です。

・変数名が配列のキーとなります。

・GROBALSの変数名にはドルマークを使用しません。

PHP 8.1.0以降

$GLOBALSはグローバルなシンボルテーブルの読み取り専用のコピーになりました。

つまり、$GLOBALSによって取得したグローバル変数の値を変更しても、元のグローバル変数の値は変わらないということです。

PHP 8.1.0以前

$GLOBALSは値渡しの例外とされており、$GLOBALSによって取得したグローバル変数のコピーを変更することで、元のグローバル変数の値を変更することができていました。

global

・現在の関数内でグローバル変数を使用するためのキーワード

・globalキーワードを使用することで、グローバル変数が変更可能

$x = 10;
function test() {
    global $x;
    $x = 20;
}
test();
echo $x; // 結果:20

 

 

選択肢のコードでは$GROBALSを使ってグローバル変数$iにアクセスしているため、合っています。

 

選択肢③

 

$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"

 

 

$argvは、スクリプトに渡された引数の配列であり、$argv[0]はスクリプト自身の名前を表します。その後ろに、スクリプトに渡された引数が順番に入ります。

選択肢のコマンドを実行した場合、$argvは以下のようになります。

array(
    0 => "sample.php",
    1 => "aaa",
    2 => "bb cc dd",
    3 => "999"
)

上記のように、$argvは引数を文字列の配列として受け取るため、引数に空白が含まれる場合は引用符で括る必要があります。

よって、選択肢は合っています。

 

選択肢④

 

$_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)

 

$_COOKIE

$_COOKIEは、Webブラウザから送信されたクッキー情報を取得するためのスーパーグローバル変数です。クッキーは、Webサイト上で状態を保持するために使用されます。

クッキーの値は名前と値のペアで構成されており、クッキーを作成するときに指定されます。Webブラウザがサーバーに要求を送信するたびに、クッキー情報が自動的に送信される仕組みとなります。

次の例は、Webブラウザから送信された「user_id」という名前のクッキーの値を取得し、利用する例です。

// クッキー情報の取得
if(isset($_COOKIE['user_id'])) {
    $user_id = $_COOKIE['user_id'];
    // クッキー情報を使用して何らかの処理を行う
}

 

セッション

また、次の例は、セッションを使ってページアクセス数をカウントする例です。

session_start(); // セッションを開始する

if(isset($_SESSION['count'])) {
  $_SESSION['count']++; // カウントを増やす
} else {
  $_SESSION['count'] = 1; // セッション変数を初期化する
}

echo "あなたは{$_SESSION['count']}回目の訪問です。";

上記の例では、まずセッションを開始し、次に$_SESSION変数にアクセスして、カウント用の値が格納されているかどうかを確認します。

$_SESSION変数にcountというキーが存在する場合は、その値を1増やし、存在しない場合は1を代入して初期化します。最後に、カウント用の値を出力します。

このように、$_COOKIE変数は、サーバー側でクッキー情報を処理するために非常に便利なスーパーグローバル変数といえます。

よって、選択肢は合っています。

setcookie()関数

また、PHPにはsetcookie()関数があり、これを使用することで、HTTPクッキーを設定することができます。setcookie()関数には、クッキーの名前有効期限パスドメインセキュアフラグHTTPOnlyフラグなどのパラメータを指定することができます。

以下は、setcookie()関数を使用してクッキーを設定する例です。

<?php
setcookie('name', 'value', time() + 3600, '/', '.example.com', true, true);

第6引数にtrueを設定すると、安全な接続(URLがhttpsで始まる接続)でのみクッキーを送るようにWebクライアントに通知します。

第7引数にtrueを設定すると、JavaScriptによるクッキー操作を不可にできます。

クロスサイトスクリプティング攻撃ではJavaScriptによってクッキー情報が盗み出されることが考えられるため、この設定により攻撃を困難にできます。

ABOUT ME
ヒロ
社会人4年目/25歳/食品商社で2年間営業した後、IT業界にシステムエンジニアとして転職/Java,PHP言語を扱う開発エンジニア