PHPでリファラを取得する方法について

採用はこちら

PHPでリファラを取得するには、$_SERVER['HTTP_REFERER'] を使用します。

リファラとは、ユーザーが現在のページへアクセスする前に見ていたページの情報です。

たとえば、外部サイトのリンク、自サイト内の別ページ、検索結果ページなどから遷移してきた場合、その参照元URLがリファラとして取得できることがあります。

ただし、リファラは必ず取得できる情報ではありません。

ブラウザの設定、セキュリティポリシー、直接アクセス、ブックマーク、アプリ内ブラウザ、Referrer-Policy などの影響により、空になる場合があります。

そのため、PHPでリファラを扱う場合は、取得できないことを前提に実装することが重要です。

目次

PHPでリファラを取得する基本コード

PHPでは、次のように $_SERVER['HTTP_REFERER'] を使ってリファラを取得します。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '';

echo $referer;
?>

$_SERVER['HTTP_REFERER'] に値が入っていれば、参照元URLを取得できます。

ただし、リファラが送信されていない場合、$_SERVER['HTTP_REFERER'] 自体が存在しないことがあります。

そのため、以下のように直接代入する書き方は避けたほうが安全です。

<?php
$referer = $_SERVER['HTTP_REFERER'];
?>

この書き方では、リファラが存在しない場合に警告が出る可能性があります。

実務では、次のように ?? を使って初期値を設定しておくと安全です。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? null;

if ($referer) {
    echo htmlspecialchars($referer, ENT_QUOTES, 'UTF-8');
} else {
    echo 'リファラは取得できませんでした。';
}
?>

このように書いておけば、リファラがない場合でもエラーを避けられます。

HTTP_REFERER のスペルに注意する

PHPでリファラを取得するときは、キー名を次のように書きます。

$_SERVER['HTTP_REFERER']

注意したいのは、REFERER のスペルです。

英単語として正しいスペルは referrer ですが、HTTPヘッダー名では歴史的な理由により Referer というスペルが使われています。

そのため、PHPでも HTTP_REFERER と書きます。

以下のように REFERRER と書いても、通常はリファラを取得できません。

$_SERVER['HTTP_REFERRER']

リファラ取得で値が取れない場合は、まずスペルが HTTP_REFERER になっているか確認しましょう。

リファラは「直前ページ」とは限らない

リファラは「直前のページURL」と説明されることが多いですが、厳密にはブラウザなどのクライアントがRefererヘッダーとして送信した参照元情報です。

そのため、必ずしも完全な直前ページURLが取得できるとは限りません。

たとえば、以下のようなケースがあります。

  • URL全体ではなく、ドメイン部分だけが送信される
  • リファラ自体が送信されない
  • ブラウザや拡張機能によって削除される
  • アプリ内ブラウザで期待どおり送信されない
  • リダイレクトを挟んで想定と違う値になる
  • curlやAPIクライアントなどから任意の値が送信される

そのため、リファラは「参考情報」として扱い、重要な判定には使わないようにしましょう。

リファラが取得できない主なケース

$_SERVER['HTTP_REFERER'] を使っても、常に値が入るわけではありません。

リファラが取得できない代表的なケースを紹介します。

URLを直接入力してアクセスした場合

ユーザーがブラウザのアドレスバーにURLを直接入力してアクセスした場合、基本的にリファラは送信されません。

たとえば、以下のURLを直接入力してアクセスした場合です。

https://example.com/contact/

この場合、別ページからリンクをクリックして移動したわけではないため、参照元URLが存在しません。

そのため、$_SERVER['HTTP_REFERER'] は空になる可能性があります。

ブックマークからアクセスした場合

ブラウザのブックマークからページを開いた場合も、リファラは取得できないことがあります。

ブックマークはリンク元ページを経由したアクセスではないため、参照元情報が送信されない場合があります。

ブラウザ設定や拡張機能で制限されている場合

ユーザーのブラウザ設定や拡張機能によって、リファラ送信が制限されることがあります。

特に、プライバシー保護を重視したブラウザ、広告ブロッカー、セキュリティ系の拡張機能などを利用している場合、リファラが削除されたり、送信内容が制限されたりすることがあります。

HTTPSからHTTPへ遷移した場合

HTTPSページからHTTPページへ遷移する場合、リファラが送信されないことがあります。

たとえば、以下のような遷移です。

https://example.com/page/
↓
http://sample.com/

HTTPSからHTTPへの移動は、安全性が低下する遷移です。

そのため、現在の一般的な Referrer-Policy では、セキュリティ上の理由からリファラが送信されない場合があります。

リファラを適切に扱いたい場合は、遷移先ページもHTTPSで運用することが望ましいです。

Referrer-Policyで制限されている場合

Webサイト側で Referrer-Policy が設定されている場合、送信されるリファラの内容が制限されます。

たとえば、以下のような設定があります。

Referrer-Policy: no-referrer

この場合、リファラは送信されません。

また、以下のような設定もあります。

Referrer-Policy: origin

この場合、ページURL全体ではなく、スキーム・ホスト・ポートからなるオリジンのみが送信されます。

たとえば、元ページが以下だったとします。

https://example.com/category/page.html

送信されるリファラは、次のようになります。

https://example.com/

つまり、リファラを取得できたとしても、必ずしもページURL全体が入っているとは限りません。

PHPでリファラを安全に表示する方法

リファラは外部から送られてくる値です。

画面に表示する場合は、そのまま出力せず、必ずエスケープします。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '';

if ($referer !== '') {
    echo htmlspecialchars($referer, ENT_QUOTES, 'UTF-8');
}
?>

避けたい書き方は、以下のように取得した値をそのまま出力する方法です。

<?php
echo $_SERVER['HTTP_REFERER'];
?>

リファラには想定外の文字列が入る可能性があります。

そのままHTMLに出力すると、XSSなどのセキュリティリスクにつながるおそれがあります。

そのため、HTMLに表示する場合は htmlspecialchars() を使いましょう。

リファラからドメインを取得する方法

リファラURL全体ではなく、参照元のドメインだけを取得したい場合は parse_url() を使います。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '';

if ($referer) {
    $host = parse_url($referer, PHP_URL_HOST);
    echo htmlspecialchars($host, ENT_QUOTES, 'UTF-8');
}
?>

たとえば、リファラが以下だった場合、

https://example.com/category/page.html?utm_source=test

取得できるホスト名は次のようになります。

example.com

参照元サイトを分類したい場合や、外部サイト・内部サイトを判定したい場合に便利です。

リファラからパスを取得する方法

リファラURLのパス部分だけを取得したい場合も、parse_url() を使います。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '';

if ($referer) {
    $path = parse_url($referer, PHP_URL_PATH);
    echo htmlspecialchars($path, ENT_QUOTES, 'UTF-8');
}
?>

たとえば、リファラが以下だった場合、

https://example.com/blog/php-referer.html?utm_source=google

取得できるパスは次のようになります。

/blog/php-referer.html

自サイト内で、どのページから現在のページへ移動したのかを確認したい場合に使えます。

リファラを条件分岐に使う方法

リファラを使って、アクセス元に応じた条件分岐を行うこともできます。

たとえば、Google検索からのアクセスかどうかを簡易的に判定する場合は、以下のように書けます。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '';

if (strpos($referer, 'google.') !== false) {
    echo 'Google検索からのアクセスです。';
} elseif (strpos($referer, 'yahoo.') !== false) {
    echo 'Yahoo!からのアクセスです。';
} else {
    echo 'その他のアクセスです。';
}
?>

ただし、このような判定はあくまで簡易的なものです。

リファラは取得できない場合があり、送信内容も環境によって変わります。

また、検索エンジンからの流入であっても検索キーワードまでは基本的に取得できません。

正確なアクセス解析をしたい場合は、Google Analyticsなどの解析ツールやUTMパラメータを併用するのが一般的です。

filter_var() でURLとして検証する方法

リファラをURLとして扱う場合は、filter_var() で形式を確認しておくと安全です。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '';

if ($referer && filter_var($referer, FILTER_VALIDATE_URL)) {
    echo '有効なURLです。';
} else {
    echo '有効なURLではありません。';
}
?>

HTTP_REFERER は外部から送信される値です。

URLとして使う場合でも、必ず正しいURL形式とは限りません。

そのため、リダイレクトやリンク生成に使う前に、URLとして妥当か確認することが大切です。

リファラを使って前のページに戻るリンクを作る方法

リファラを使うと、「前のページへ戻る」リンクを作成できます。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '/';
?>

<a href="<?php echo htmlspecialchars($referer, ENT_QUOTES, 'UTF-8'); ?>">前のページへ戻る</a>

ただし、この書き方では外部サイトのURLが入る可能性があります。

たとえば、外部サイトから現在のページに来た場合、戻るリンクの遷移先も外部サイトになります。

意図しない外部サイトへユーザーを誘導する可能性があるため、実務では自サイト内のURLだけを許可する実装にしたほうが安全です。

自サイト内のリファラだけを許可する方法

戻るリンクやリダイレクトにリファラを使う場合は、自サイト内のURLだけを許可すると安全です。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '';
$defaultUrl = '/';
$backUrl = $defaultUrl;

if ($referer && filter_var($referer, FILTER_VALIDATE_URL)) {
    $allowedHosts = [
        'example.com',
        'www.example.com',
    ];

    $refererHost = parse_url($referer, PHP_URL_HOST);

    if (in_array($refererHost, $allowedHosts, true)) {
        $backUrl = $referer;
    }
}
?>

<a href="<?php echo htmlspecialchars($backUrl, ENT_QUOTES, 'UTF-8'); ?>">前のページへ戻る</a>

このコードでは、許可するホスト名をあらかじめ配列で指定しています。

リファラのホスト名が example.com または www.example.com の場合だけ、戻るリンクとして使用します。

それ以外の場合は、初期値として指定した / に戻します。

このようにしておくと、意図しない外部URLへの誘導を防ぎやすくなります。

リファラを使ってリダイレクトする方法

リファラを使って前のページへリダイレクトする場合も、自サイト内のURLかどうかを確認してから処理しましょう。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '';
$defaultUrl = '/';
$redirectUrl = $defaultUrl;

if ($referer && filter_var($referer, FILTER_VALIDATE_URL)) {
    $allowedHosts = [
        'example.com',
        'www.example.com',
    ];

    $refererHost = parse_url($referer, PHP_URL_HOST);

    if (in_array($refererHost, $allowedHosts, true)) {
        $redirectUrl = $referer;
    }
}

header('Location: ' . $redirectUrl);
exit;

単純に以下のように書くこともできます。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '/';

header('Location: ' . $referer);
exit;

しかし、この書き方はおすすめできません。

リファラには外部URLが入る可能性があり、場合によってはオープンリダイレクトの原因になります。

リダイレクト先として使う場合は、許可するホスト名をチェックするなど、安全な実装にしましょう。

実務で使いやすいリファラ取得関数

毎回 $_SERVER['HTTP_REFERER'] を直接扱うのではなく、関数化しておくと便利です。

<?php
function getReferer(): ?string
{
    $referer = $_SERVER['HTTP_REFERER'] ?? null;

    if (!$referer) {
        return null;
    }

    if (!filter_var($referer, FILTER_VALIDATE_URL)) {
        return null;
    }

    return $referer;
}

使うときは、次のように書きます。

<?php
$referer = getReferer();

if ($referer) {
    echo htmlspecialchars($referer, ENT_QUOTES, 'UTF-8');
} else {
    echo 'リファラなし';
}
?>

この関数では、リファラが存在しない場合や、URLとして不正な場合に null を返します。

自サイト内のリファラだけを返す関数

戻るリンクやリダイレクトに使う場合は、自サイト内のリファラだけを返す関数にしておくと便利です。

<?php
function getInternalReferer(string $default = '/'): string
{
    $referer = $_SERVER['HTTP_REFERER'] ?? '';

    if (!$referer || !filter_var($referer, FILTER_VALIDATE_URL)) {
        return $default;
    }

    $allowedHosts = [
        'example.com',
        'www.example.com',
    ];

    $refererHost = parse_url($referer, PHP_URL_HOST);

    if (!in_array($refererHost, $allowedHosts, true)) {
        return $default;
    }

    return $referer;
}

戻るリンクで使う場合は、次のように書きます。

<?php
$backUrl = getInternalReferer('/');
?>

<a href="<?php echo htmlspecialchars($backUrl, ENT_QUOTES, 'UTF-8'); ?>">前のページへ戻る</a>

リダイレクトで使う場合は、以下のようにします。

<?php
$redirectUrl = getInternalReferer('/');

header('Location: ' . $redirectUrl);
exit;

許可するホスト名を明示しておけば、外部サイトへの意図しないリダイレクトを防ぎやすくなります。

セッションで前ページを管理する方法

「前のページへ戻る」機能を作りたい場合、HTTP_REFERER に頼るよりも、セッションで自サイト内の遷移履歴を管理する方法もあります。

<?php
session_start();

$currentUrl = $_SERVER['REQUEST_URI'] ?? '/';
$previousUrl = $_SESSION['current_url'] ?? '/';

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'GET') {
    $_SESSION['current_url'] = $currentUrl;
}
?>

戻るリンクでは、以下のように $previousUrl を使います。

<a href="<?php echo htmlspecialchars($previousUrl, ENT_QUOTES, 'UTF-8'); ?>">前のページへ戻る</a>

この方法は、リファラが送信されない環境でも、自サイト内の遷移をある程度管理できる点がメリットです。

ただし、すべてのページを保存すると、フォーム送信ページ、確認画面、ログインページなど、戻り先として適切でないURLが保存される場合があります。

そのため、実際のサイトでは保存対象のページを制限するなど、サイト構造に合わせた調整が必要です。

JavaScriptの document.referrer との違い

リファラは、JavaScriptでも取得できます。

JavaScriptでは、以下のように document.referrer を使います。

console.log(document.referrer);

PHPとJavaScriptの違いは、取得するタイミングと場所です。

方法実行場所主な用途
$_SERVER['HTTP_REFERER']サーバー側リダイレクト、サーバー側の条件分岐、ログ保存
document.referrerブラウザ側表示後の処理、フロントエンド側の条件分岐

PHPの $_SERVER['HTTP_REFERER'] は、ページが表示される前にサーバー側で取得します。

一方、JavaScriptの document.referrer は、ページがブラウザに読み込まれた後に取得します。

ただし、どちらもリファラ情報に依存しているため、必ず取得できるわけではありません。

WordPressでリファラを取得する方法

WordPressでも、PHPと同じように $_SERVER['HTTP_REFERER'] を使うことはできます。

$referer = $_SERVER['HTTP_REFERER'] ?? '';

ただし、WordPressでは wp_get_referer() を使う方法があります。

$referer = wp_get_referer();

wp_get_referer() は、リファラが取得できる場合はURL文字列を返し、取得できない場合は false を返します。

そのため、以下のように戻り値を確認して使います。

<?php
$referer = wp_get_referer();

if ($referer !== false) {
    echo esc_url($referer);
}
?>

WordPress内でURLをHTMLに出力する場合は、htmlspecialchars() よりも esc_url() を使うのが一般的です。

WordPressでリファラへ安全にリダイレクトする方法

WordPressでリファラへリダイレクトしたい場合は、wp_safe_redirect() を使うと安全です。

<?php
$referer = wp_get_referer();

if ($referer) {
    wp_safe_redirect($referer);
    exit;
}

wp_safe_redirect(home_url('/'));
exit;
?>

wp_safe_redirect() は、許可されていない外部ホストへのリダイレクトを防ぎやすい関数です。

また、wp_safe_redirect() は呼び出しただけでは処理が終了しません。

そのため、リダイレクト後は exit; を書く必要があります。

リファラをアクセス解析に使う場合の注意点

リファラは、簡易的な参照元確認には便利です。

たとえば、以下のような情報を確認したい場合に使えます。

  • 外部サイトから来たか
  • 自サイト内のどのページから移動したか
  • 検索エンジン経由の可能性があるか
  • SNSや広告ページから来た可能性があるか

ただし、リファラだけで正確なアクセス解析を行うのは難しいです。

理由は以下の通りです。

  • リファラが送信されないことがある
  • URL全体ではなくオリジンだけになることがある
  • ブラウザやアプリによって挙動が異なる
  • ユーザー環境によって削除されることがある
  • リダイレクトを挟むと想定と違う値になることがある
  • 任意の値が送信される可能性がある

マーケティング目的で流入元を正確に把握したい場合は、リファラだけに頼らず、UTMパラメータを併用するのがおすすめです。

UTMパラメータを併用する方法

広告、SNS、メルマガ、キャンペーンなどの流入元を分析したい場合は、URLにUTMパラメータを付与します。

たとえば、以下のようなURLです。

https://example.com/lp/?utm_source=twitter&utm_medium=social&utm_campaign=spring_sale

PHPで取得する場合は、次のようにします。

<?php
$utmSource = $_GET['utm_source'] ?? '';
$utmMedium = $_GET['utm_medium'] ?? '';
$utmCampaign = $_GET['utm_campaign'] ?? '';
?>

リファラは「どのサイトから来た可能性があるか」を把握する補助情報として使い、広告やキャンペーンの効果測定にはUTMパラメータを使うとよいでしょう。

リファラをログに保存する方法

リファラをログとして保存したい場合は、ファイルやデータベースに記録できます。

簡単なファイル保存の例は以下です。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? 'no_referer';
$accessTime = date('Y-m-d H:i:s');
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';

$log = "{$accessTime}\t{$ip}\t{$referer}\n";

file_put_contents(__DIR__ . '/referer.log', $log, FILE_APPEND | LOCK_EX);
?>

ただし、ログ保存では以下の点に注意が必要です。

  • ログファイルをWeb公開ディレクトリに置かない
  • ファイルサイズが大きくなりすぎないようにする
  • IPアドレスなど個人情報に該当しうる情報の扱いに注意する
  • 保存期間を決める
  • 不正な文字列が入る可能性を考慮する
  • 必要に応じてアクセス制限を行う

本格的なアクセス解析を行う場合は、自作ログだけでなく、解析ツールやサーバーログの利用も検討しましょう。

リファラをセキュリティ判定に使う場合の注意点

リファラは、セキュリティ上の重要な判定に単独で使うべきではありません。

たとえば、以下のような使い方は危険です。

<?php
$referer = $_SERVER['HTTP_REFERER'] ?? '';

if (strpos($referer, 'example.com/form') !== false) {
    // 許可
} else {
    // 拒否
}
?>

このような実装では、リファラがない場合に正しいユーザーを拒否してしまう可能性があります。

また、通常のブラウザ操作ではRefererヘッダーを自由に書き換えられないものの、curl、APIクライアント、プロキシ、ボットなどを使えば任意の値を送信できます。

そのため、リファラだけで「正しいページから来たかどうか」を判断するのは避けましょう。

フォーム送信元の確認にはCSRFトークンを使う

フォーム送信の保護では、リファラチェックだけに依存せず、CSRFトークンを使うのが基本です。

フォーム側では、セッションに保存したトークンをhiddenフィールドに入れます。

<?php
session_start();

if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
?>

<form method="post" action="submit.php">
    <input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($_SESSION['csrf_token'], ENT_QUOTES, 'UTF-8'); ?>">
    <button type="submit">送信</button>
</form>

送信先では、セッション内のトークンとPOSTされたトークンを比較します。

<?php
session_start();

$token = $_POST['csrf_token'] ?? '';

if (!hash_equals($_SESSION['csrf_token'] ?? '', $token)) {
    exit('不正なリクエストです。');
}

echo '正常な送信です。';
?>

必要に応じて、Origin ヘッダーや Referer ヘッダーの確認を補助的な防御策として併用することもあります。

ただし、基本はCSRFトークンによる検証です。

リファラチェックだけに依存しないようにしましょう。

PHPでリファラを扱うときのポイント

PHPでリファラを扱うときは、以下の点を押さえておきましょう。

ポイント内容
基本の取得方法$_SERVER['HTTP_REFERER'] を使う
存在チェック$_SERVER['HTTP_REFERER'] ?? '' のように書く
表示時の対策htmlspecialchars() でエスケープする
URL検証filter_var() でURL形式を確認する
リダイレクト許可したホストだけに限定する
WordPresswp_get_referer()wp_safe_redirect() を使う
アクセス解析UTMパラメータや解析ツールと併用する
セキュリティリファラだけに依存しない
フォーム保護CSRFトークンを使う

まとめ

PHPでリファラを取得する基本的な方法は、以下の通りです。

$referer = $_SERVER['HTTP_REFERER'] ?? '';

ただし、リファラは必ず取得できるものではありません。

直接アクセス、ブックマーク、ブラウザ設定、拡張機能、HTTPSからHTTPへの遷移、Referrer-Policy などの影響により、値が空になることがあります。

また、取得できた場合でも、URL全体ではなくオリジンだけが送信されるケースもあります。

さらに、リファラは外部から送信される値であるため、信頼しすぎてはいけません。

画面に表示する場合は htmlspecialchars() でエスケープし、リダイレクト先として使う場合は自サイト内URLかどうかを検証する必要があります。

アクセス解析では、リファラは参照元を知るための補助情報として使えます。

しかし、広告やSNS、メルマガなどの流入を正確に分析したい場合は、UTMパラメータやアクセス解析ツールを併用するのがおすすめです。

セキュリティ対策では、リファラだけを根拠にアクセス許可やフォーム送信の正当性を判断するのは避けましょう。

フォーム送信の保護には、CSRFトークンを使うのが基本です。

リファラは便利な情報ですが、取得できないことや内容が制限されることがあります。

そのため、PHPで扱う際は「取得できれば参考にする情報」として使い、重要な処理には検証や代替手段を組み合わせることが大切です。

以上、PHPでリファラを取得する方法についてでした。

最後までお読みいただき、ありがとうございました。

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