海外からのアクセスを振り分ける[php]
海外からのアクセスを判別して別ページに振り分ける方法を紹介します。phpです。
まえがき
この前とある案件で「海外からアクセスがあったら海外用のページに飛ばしたい。でもその海外用のページから日本語ページにリンクを張って日本語のページも見れるようにしたい」という要望を受けました。
この要望を実現するために、クリアすべき点をザックリ挙げると
- 海外からのアクセスを判別して振り分け
- 海外用ページから日本語ページにアクセスされた時を判別
この2点です。2つ目はこの記事のタイトルから見れば若干蛇足ですがついでに解説していこうと思います。
海外からのアクセスを判別して振り分けるいくつかの方法
調べたところ、海外からのアクセスを判別する方法の選択肢は3つ程あるようです。
- 「php」で判別
- 「.htaccess」で判別
- 「javascript」で判別
KoToRiはphpを選択しました。
「php」で判別する方法を選択した理由
「php」で判別する方法というのが、ブラウザの設定言語を取得して海外からのアクセスかどうかを判別するという方法です。
なので「海外からのアクセス」というより「外国人からのアクセス」を判別しているといった感じでしょうか。
例えば日本にいるアメリカ人は恐らくブラウザの設定言語は英語でしょう。そういった人も対象に含むことができます。
あと個人的に「.htaccess」や「javascript」より「php」のほうが好きだからです。
一応、「.htaccess」での判別や「javascript」での判別がダメな理由を書いたのですが完全に蛇足なので要らない人は読み飛ばしてください。
「.htaccess」で判別するのがダメな理由
ダメって分けじゃないんだけどWordPressでサイトを構築していると「.htaccess」に既にWordPressのリダイレクトの記述が書かれてますよね。
そこに変に違うリダイレクトの記述すると元のリダイレクトとコンフリクトしちゃってWordPressで正常にページ閲覧できなくなるという現象に多々遭遇してるのですよ。
なので「.htaccess」以外の選択肢があるならとりあえずそっちを利用したいですね。
また、「.htaccess」で判別する方法自体がKoToRi的には微妙でした。
現在日本国内に割り当てられているIPアドレスを全て(2014年12月18日の時点で202,491,904個位)「.htaccess」に記述してリダイレクトするとか、
カントリーコードで識別して特定の国からのアクセスをリダイレクトする方法もあるけど精度が低そうだったりとか、
なんか現実的じゃないな~と思いました。
この辺は下記に詳しく書いてあります。
http://www.yuzuriha.sakura.ne.jp/~akikan/kaigai/kaigai6.html
http://www.cgis.biz/tools/access/
「javascript」で判別するのがダメな理由
KoToRiはリダイレクト関係を「javascript」や「html」の「meta」タグで行うのは止めたほうが良いと思います。
当たり前なのですが、「javascript」や「html」は一回ブラウザに読み込まれた上で実行されるものなので、一瞬リダイレクト前のページが見えちゃったりするんですよね。
よろしくありません。なので無しです。
海外からのアクセスを「php」で判別して振り分ける方法
phpに用意されている環境変数「HTTP_ACCEPT_LANGUAGE」を利用します。
「HTTP_ACCEPT_LANGUAGE」にはブラウザに設定されている言語が返ってきます。
ここで気をつけてほしいのはブラウザに設定できる言語は1個じゃないということです。
この画像はchromeの言語設定画面です。
- 英語
- 英語(アメリカ合衆国)
- 日本語
この3つの言語が設定されているのがわかると思います。
「英語」と「英語(アメリカ合衆国)」の違いはイギリス英語かアメリカ英語かの違いでしょう。
今回紹介するコードでは
優先度がより高く設定されている言語を判別します
「優先度が高い」=「上に表示されている言語」ということです。
例えばChromeは言語をドラッグして並び替えることが可能です。
動作確認の際はブラウザの設定気をつけてください。
では早速、海外からのアクセスを判別する「php」コードを見てみましょう。
<?php $languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); $languages = array_reverse($languages); $result = ''; foreach ($languages as $language) { if (preg_match('/^en/i', $language)) { $result = 'English'; header("Location: /english"); } elseif (preg_match('/^ja/i', $language)) { $result = 'Japanese'; header("Location: /"); } } if ($result == '') { $result = 'Japanese'; header("Location: /"); }
2行目の「explode(‘,’, $_SERVER[‘HTTP_ACCEPT_LANGUAGE’])」で取得したブラウザの言語コードを配列に変換してforeachで回すというコードです。
結果、ブラウザの言語コードに”en”が含まれていれば「/english」に飛ばします。
やってることはいたってシンプルですね。
これでブラウザの言語設定によって表示するページを振り分けることができました。
因みにブラウザが送ってくる言語コードの一覧が下記にアップされています。
http://www.futomi.com/lecture/env_var/http_accept_language.html
海外用ページから日本語ページにアクセスした時を判別する
海外用ページから日本語ページにアクセスした時のみ、海外用ページにリダイレクトさせず普通に日本語ページを表示する方法です。
まえがきでも書きましたがこれは蛇足です。
まず「海外用ページから日本語ページにアクセスした時の判別」ですが、これは「php」の「$_GET」を利用すれば良いかと思います。
海外用ページからのリンクは「http://○○○?lang=ja」とでもしてパラメータ渡してやって、上で紹介したコードをちょっと変更して「if文」追加してやれば、
海外用ページからに日本語ページにアクセスした場合は普通に日本語ページを表示する
といったことができます。
今回の要望ではトップページのみ振り分ければ良かったので下記のようなコードで実現できました。
<?php $languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); $languages = array_reverse($languages); $result = ''; foreach ($languages as $language) { if (preg_match('/^en/i', $language)) { $result = 'English'; } elseif (preg_match('/^ja/i', $language)) { $result = 'Japanese'; } } if ($result == '') { $result = 'Japanese'; } if(is_home()){ $lang = $_GET["lang"]; if(!$lang&&$result=='English'){ header("Location: /english?lang=en"); } }
まとめ
今回紹介した海外からのアクセスを「php」で判別する方法は結構主流で、コードの動作確認のためにブラウザの設定を英語にして色々サイトを回ってたんですが言語を選べるサイト等は結構英語サイトに飛ばされました。やはりブラウザの言語を判断基準にしているところが多いと思います。
参考サイト
ありがとうございます。
Pingback: PHPでブラウザの使用言語を解析してページを振り分ける方法 | 個人的プログラムの備忘録()