1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【PHP】$_SERVERが環境によって想定どうりに動いてくれない【落とし穴】

Posted at

はじめに

PHPの$_SERVERでドメインまでのURLを取得しようとしたときに、本番環境と検証環境、開発環境で挙動がことなることではまったので共有。
AWSを使用した環境で陥りがちなミスかと思います。

具体的な内容

ミスっていたときのコード

開発環境はオンプレのサーバー上にあり、検証・本番環境はAWSサーバー上にあります。開発環境でのプロトコルはhttpですが、検証・本番環境はhttpsです。
画像を取得する際ためにドメインまでのURLを取得するために以下のように書きました。

$domain = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http' . $_SERVER['HOST'];

この書き方ではAWS上の検証環境・本番環境に上げた際にhttpsだと判断されず思うような挙動になりませんでした。

想定した動作をしなかった原因

AWS上でアプリケーションサーバの前にロードバランサーを置いていて、サイト自体はHTTPSだが、
実際のSSL暗号化処理はロードバランサーのSSLアクセラレータ機能が行っており、ウェブサーバはHTTP平文通信をしているため。

修正するにあたって参考にした記事

$_SERVER は、ヘッダ、パス、スクリプトの位置のような 情報を有する配列です。この配列のエントリは、Web サーバーにより 生成されます。全ての Web サーバーがこれら全てを提供する保証はありません。

$http_x_forwarded_protoを使うとクライアントがロードバランサーへの接続に使用したプロトコルを識別できます。
$http_x_forwarded_protoがhttpsではなかった時にhttpsでリダイレクトします。

想定された挙動になった際のコード

$domain = (isset($_SERVER['http_x_forwarded_proto']) && $_SERVER['http_x_forwarded_proto'] === 'https') ? 'https' : 'http' . $_SERVER['HOST'];

まとめ

今回は開発環境と検証・本番環境の環境の差異で起こしてしまったミスです。公式ドキュメントの一番上にヒントがありましたが他の記事を読むまで読み飛ばしていました、、、
開発環境での確認では気づきにくい部分かと思いますので知っておくことが大事な落とし穴かと思います。他の方法や解釈が間違っている箇所がありましたらぜひコメントで指摘をお願いいたします。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?