この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:3
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: $_SERVER
SEOタイトル: PHP $_SERVER スーパーグローバル変数(DOCUMENT_ROOT / PHP_SELF / REQUEST_URI / HTTP_USER_AGENT / 一覧)

この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;background:#fffbea;border:1px solid #f4c430;margin:1em 0;width:100%"><tr><td style="background:#f4c430;color:#000;font-weight:bold;padding:8px">この記事の要点</td></tr><tr><td style="padding:10px"><ul><li><strong>$_SERVER</strong> は<strong>サーバ情報・実行環境・クライアントから送信されたヘッダ</strong>を格納する PHP スーパーグローバル変数</li><li><code>$_SERVER["DOCUMENT_ROOT"]</code> や <code>$_SERVER["PHP_SELF"]</code> のように<strong>要素キー</strong>で値を取り出す</li><li><strong>クライアント由来の値</strong>(<code>HTTP_*</code> / <code>REQUEST_URI</code> / <code>QUERY_STRING</code> 等)は<strong>偽装可能</strong>のため、無加工で出力すると XSS / ヘッダインジェクションになる</li><li>PHP-CLI と PHP-FPM / mod_php で<strong>使えるキーが異なる</strong>。<code>HTTP_HOST</code> や <code>REQUEST_URI</code> は Web サーバ経由のみ</li><li>配列は <code>print_r($_SERVER)</code> / <code>var_dump($_SERVER)</code> で<strong>全キー</strong>を確認できる</li></ul></td></tr></table>
<h2>$_SERVER とは</h2>

<p><strong>$_SERVER</strong> は PHP の<strong>スーパーグローバル変数</strong>(どこからでもアクセスできる組み込み配列)の 1 つで、<strong>Web サーバや実行環境、クライアントから送信された情報</strong>がキー付きで格納されています。Web アプリケーションでリクエスト元の URL、IP、ユーザーエージェント、リファラなどを取得するときに使います。</p>

<h2>基本構文</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">echo $_SERVER[&apos;DOCUMENT_ROOT&apos;];     // /var/www/html
echo $_SERVER[&apos;PHP_SELF&apos;];          // /index.php
echo $_SERVER[&apos;REQUEST_URI&apos;];       // /index.php?id=10
echo $_SERVER[&apos;HTTP_USER_AGENT&apos;];   // Mozilla/5.0 ...
echo $_SERVER[&apos;REMOTE_ADDR&apos;];       // 接続元 IP</code></pre>
<h2>主要な要素一覧</h2>

<h3>パス / 実行ファイル系</h3>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>キー</th><th>意味</th><th>例</th></tr></thead>
<tbody>
<tr><td><code>DOCUMENT_ROOT</code></td><td>ドキュメントルートのフルパス</td><td><code>/var/www/html</code></td></tr>
<tr><td><code>SCRIPT_FILENAME</code></td><td>実行中スクリプトの絶対パス</td><td><code>/var/www/html/index.php</code></td></tr>
<tr><td><code>SCRIPT_NAME</code></td><td>実行中スクリプトのドキュメントルートからの相対パス</td><td><code>/index.php</code></td></tr>
<tr><td><code>PHP_SELF</code></td><td>同上(path_info を含む)</td><td><code>/index.php/foo</code></td></tr>
</tbody>
</table>

<h3>リクエスト URL 系</h3>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>キー</th><th>意味</th><th>例</th></tr></thead>
<tbody>
<tr><td><code>REQUEST_URI</code></td><td>クエリを含むリクエストパス</td><td><code>/article?id=10</code></td></tr>
<tr><td><code>QUERY_STRING</code></td><td>?以降のクエリ文字列</td><td><code>id=10&page=2</code></td></tr>
<tr><td><code>REQUEST_METHOD</code></td><td>HTTP メソッド</td><td><code>GET</code> / <code>POST</code></td></tr>
<tr><td><code>HTTPS</code></td><td>HTTPS なら <code>on</code></td><td><code>on</code> / 未設定</td></tr>
<tr><td><code>SERVER_PROTOCOL</code></td><td>HTTP バージョン</td><td><code>HTTP/1.1</code></td></tr>
</tbody>
</table>

<h3>クライアント / 接続元系</h3>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>キー</th><th>意味</th><th>例</th></tr></thead>
<tbody>
<tr><td><code>REMOTE_ADDR</code></td><td>接続元 IP</td><td><code>203.0.113.10</code></td></tr>
<tr><td><code>REMOTE_PORT</code></td><td>接続元ポート</td><td><code>54321</code></td></tr>
<tr><td><code>HTTP_USER_AGENT</code></td><td>ブラウザの UA 文字列</td><td><code>Mozilla/5.0 ...</code></td></tr>
<tr><td><code>HTTP_REFERER</code></td><td>遷移元 URL</td><td><code>https://google.com/</code></td></tr>
<tr><td><code>HTTP_ACCEPT_LANGUAGE</code></td><td>言語設定</td><td><code>ja,en;q=0.8</code></td></tr>
<tr><td><code>HTTP_HOST</code></td><td>リクエスト先ホスト</td><td><code>example.com</code></td></tr>
<tr><td><code>HTTP_X_FORWARDED_FOR</code></td><td>プロキシ経由の元 IP</td><td><code>203.0.113.10</code></td></tr>
</tbody>
</table>

<h3>サーバ系</h3>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>キー</th><th>意味</th><th>例</th></tr></thead>
<tbody>
<tr><td><code>SERVER_NAME</code></td><td>サーバ名(VirtualHost 名)</td><td><code>example.com</code></td></tr>
<tr><td><code>SERVER_ADDR</code></td><td>サーバ IP</td><td><code>10.0.0.5</code></td></tr>
<tr><td><code>SERVER_PORT</code></td><td>サーバポート</td><td><code>443</code></td></tr>
<tr><td><code>SERVER_SOFTWARE</code></td><td>Web サーバの種類</td><td><code>nginx/1.25.0</code></td></tr>
<tr><td><code>REQUEST_TIME</code></td><td>リクエスト受付時刻(UNIX 時刻)</td><td><code>1718000000</code></td></tr>
<tr><td><code>REQUEST_TIME_FLOAT</code></td><td>同(マイクロ秒精度)</td><td><code>1718000000.123</code></td></tr>
</tbody>
</table>

<h2>現在の完全な URL を組み立てる</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">function currentUrl(): string {
    $scheme = (!empty($_SERVER[&apos;HTTPS&apos;]) && $_SERVER[&apos;HTTPS&apos;] !== &apos;off&apos;)
        ? &apos;https&apos; : &apos;http&apos;;
    $host = $_SERVER[&apos;HTTP_HOST&apos;] ?? &apos;localhost&apos;;
    $uri  = $_SERVER[&apos;REQUEST_URI&apos;] ?? &apos;/&apos;;
    return $scheme . &apos;://&apos; . $host . $uri;
}

echo currentUrl();
// https://example.com/article?id=10</code></pre>
<h2>クライアント IP を安全に取る</h2>

<p>ロードバランサや CDN(Cloudflare 等)の背後では <code>REMOTE_ADDR</code> はプロキシの IP になります。元のクライアント IP は <code>HTTP_X_FORWARDED_FOR</code> から取得しますが、<strong>信頼できるプロキシ経由かを検証</strong>しないと偽装されます。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">function clientIp(): string {
    // 信頼できる前段プロキシ(CDN / LB)の IP リスト
    $trusted = [&apos;10.0.0.1&apos;, &apos;10.0.0.2&apos;];
    $remote  = $_SERVER[&apos;REMOTE_ADDR&apos;] ?? &apos;&apos;;

    if (in_array($remote, $trusted, true)
        && !empty($_SERVER[&apos;HTTP_X_FORWARDED_FOR&apos;])) {
        // 左端が元クライアント
        $forwarded = explode(&apos;,&apos;, $_SERVER[&apos;HTTP_X_FORWARDED_FOR&apos;]);
        return trim($forwarded[0]);
    }
    return $remote;
}</code></pre>
<h2>安全に出力する</h2>

<p><strong>$_SERVER のクライアント由来の値(HTTP_*, REQUEST_URI, PHP_SELF など)は偽装可能</strong>です。HTML や属性に埋め込むときは必ずエスケープします。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">// NG: そのまま出力すると XSS
echo $_SERVER[&apos;HTTP_USER_AGENT&apos;];

// OK: htmlspecialchars でエスケープ
echo htmlspecialchars(
    $_SERVER[&apos;HTTP_USER_AGENT&apos;] ?? &apos;&apos;,
    ENT_QUOTES | ENT_HTML5,
    &apos;UTF-8&apos;
);

// フォームの action に PHP_SELF を埋め込むのは特に危険
// <form action="<?= $_SERVER[&apos;PHP_SELF&apos;] ?>"> は XSS の温床
// ハードコードか htmlspecialchars 必須</code></pre>
<h2>全キーを確認する</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">// 全キー値を出力(デバッグ用、本番では出さない)
echo &apos;<pre>&apos;;
print_r($_SERVER);
echo &apos;</pre>&apos;;

// または var_dump
var_dump($_SERVER);</code></pre>
<h2>CLI 実行時の違い</h2>

<p>PHP を <code>php script.php</code> のように<strong>コマンドラインから実行</strong>すると、<code>HTTP_*</code> や <code>REQUEST_URI</code> など Web リクエスト由来の要素は<strong>存在しません</strong>。代わりに <code>argv</code> / <code>argc</code> が使えます。</p>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-php">// CLI のみ
echo $_SERVER[&apos;argv&apos;][0];  // スクリプトファイル名
echo $_SERVER[&apos;argc&apos;];     // 引数の個数
print_r($_SERVER[&apos;argv&apos;]); // 全引数

// 環境分岐
if (php_sapi_name() === &apos;cli&apos;) {
    echo "CLI mode\n";
} else {
    echo "Web mode\n";
}</code></pre>
<h2>$_SERVER と関連スーパーグローバル</h2>

<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>変数</th><th>用途</th></tr></thead>
<tbody>
<tr><td><code>$_SERVER</code></td><td>サーバ / 環境 / リクエスト情報</td></tr>
<tr><td><code>$_GET</code></td><td>クエリ文字列の値</td></tr>
<tr><td><code>$_POST</code></td><td>POST ボディの値</td></tr>
<tr><td><code>$_COOKIE</code></td><td>Cookie の値</td></tr>
<tr><td><code>$_SESSION</code></td><td>セッション変数</td></tr>
<tr><td><code>$_FILES</code></td><td>アップロードファイル</td></tr>
<tr><td><code>$_REQUEST</code></td><td>$_GET + $_POST + $_COOKIE のマージ</td></tr>
<tr><td><code>$_ENV</code></td><td>環境変数</td></tr>
</tbody>
</table>

<h2>FAQ</h2>

<p><strong>Q: HTTP_HOST と SERVER_NAME どちらを使うべき?</strong><br />
A: <code>HTTP_HOST</code> はクライアントが送ったヘッダ(偽装可)、<code>SERVER_NAME</code> はサーバ設定(VirtualHost)由来。多くの場合 <code>HTTP_HOST</code> が便利ですが、絶対 URL を組む際は<strong>許可ホストのホワイトリスト検証</strong>を入れます。</p>

<p><strong>Q: REQUEST_TIME と time() の違いは?</strong><br />
A: <code>$_SERVER['REQUEST_TIME']</code> はリクエスト受付時刻で固定。<code>time()</code> は呼び出し時の現在時刻。リクエスト全体で同じ「現在時刻」を扱いたいなら REQUEST_TIME。</p>

<h2>関連</h2>

<ul>
<li>スーパーグローバル変数 — PHP の組み込み配列</li>
<li>$_GET / $_POST — リクエストパラメータ</li>
<li>htmlspecialchars — XSS 対策のエスケープ</li>
<li>filter_input — INPUT_SERVER 等で安全に取得</li>
</ul>