目次
ウェブブラウザの国・言語
PHP のスーパーグローバル変数 $_SERVER に含まれる HTTP_ACCEPT_LANGUAGE の値を取得して、ウェブブラウザの言語の設定を判定するテストを行ってみました。ウェブページを閲覧しているユーザーの言語設定、優先される国の言葉に合わせて、ウェブページの表示を分岐したりするのに使用出来れば便利そうです。
ACCEPT の英語の意味を調べてみますと、受諾、受け入れるなどの意味を持つようです。
- PHP: $_SERVER - Manual
- http://php.net/manual/ja/reserved.variables.server.php
HTTP_ACCEPT_LANGUAGE の存在
HTTP_ACCEPT_LANGUAGE のキー(添字)は、 $_SERVER 配列の中に必ず存在しているということでは無いようです。ある場合は、ja (日本語)、 en(英語) などの言語名が値として入ってくるようです。
- Accept-Language - HTTP | MDN
- https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Accept-Language
$_SERVER のテスト
まずは、 $_SERVER の内容を var_dump して確認してみます。以下の PHP のコードを書いてみました。実行してみます。
<?php
var_dump( $_SERVER ); //データの構造をわかりやすく出力してくれる var_dump 関数です。
?>
そうすると、以下のような内容が出力されると思います。結果を見てみると、 HTTP_ACCEPT_LANGUAGE キーが存在するようです。 HTTP_ACCEPT_LANGUAGE キー以外の値は伏せ字 xxx にしていますが、 $_SERVER 配列の中身が一覧で表示されました。
array(xxx) { ["xxx"]=> xxx ["xxx"]=> xxx ["xxx"]=> xxx ["HTTP_ACCEPT_LANGUAGE"]=> string(23) "ja,en-US;q=0.7,en;q=0.3" //言語名らしき値が入っています。 ["xxx"]=> xxx
["xxx"]=> xxx
["xxx"]=> xxx
}
上記では、 var_dump の出力結果から、目視でキーの存在を確認しましたが、 PHP の array_key_exists という関数を使用すれば、配列の中に指定のキーが存在するかどうかの真偽値を取得できるようです。
- PHP: array_key_exists - Manual
- http://php.net/manual/ja/function.array-key-exists.php
array_key_exists 関数を使用した PHP コードを書いてみました。実行してみます。
<?php
var_dump( array_key_exists( "HTTP_ACCEPT_LANGUAGE" , $_SERVER ) ); //$_SERVER 配列から HTTP_ACCEPT_LANGUAGE のキーを探します。
?>
結果を見てみると、 true になっています。 $_SERVER 配列の中に HTTP_ACCEPT_LANGUAGE のキーがあるようです。
bool(true) //真偽値が戻ってきました。
私が独自に考えたキー名 original_key を array_key_exists 関数で検索するとどうなるでしょうか。検索対象の配列は、 $_SERVER です。試してみます。
<?php
var_dump( array_key_exists( "original_key" , $_SERVER ) ); //$_SERVER から original_key を検索してみる。
?>
結果は false になりました。配列の中にキーが存在していません。
bool(false) //キーが見つからなかったようです。
以下のように存在しないキーの値を取得しようとすると「 PHP Notice: Undefined index: original_key in xxx.php on line xxx 」のようなエラーが発生するようです。
<?php
var_dump( $_SERVER["original_key"] ); //このキーはないので軽い、画面が真っ白にならない位のエラーが発生します。
?>
言語名を取得
上述を踏まえて、 HTTP_ACCEPT_LANGUAGE の値のみを取得してみたいと思います。下記の PHP のコードを試してみます。ウェブブラウザの Firefox で出力結果を表示してみます。
<?php
if( array_key_exists( "HTTP_ACCEPT_LANGUAGE" , $_SERVER ) ){ //指定のキーが存在する場合のみ {} 内側の次の処理へ。
var_dump( $_SERVER["HTTP_ACCEPT_LANGUAGE"] ); //値を出力します。
}
?>
出力結果は以下のようになりました。日本語を示す ja から始まる文字列が出力されました。
string(23) "ja,en-US;q=0.7,en;q=0.3" //string は文字列という意味です。 j から 3 までの 23 文字です。
ja,en-US;q=0.7,enc を分解して見てみます。
- ja
- en-US;q=0.7
- en;q=0.3
の 3 つの情報がカンマ( , の記号)区切りで記載されています。
ja , en-US , en は、日本語、英語(アメリカ合衆国)、英語を示す言語名のようです。
;q=0.7 , ;q=0.3 は、重み付けの数値のようで、この数値で言語判定の優先度が決まっているようです。 ;q= 指定なしの ja の初期値は 1 のようで、 q の最大値のようです。その後に続く en-US , en 言語は、少しずつ小さい数字になっています。数値が小さくなると優先度が低くなるようです。
- Quality values - MDN Web Docs Glossary: Definitions of Web-related terms | MDN
- https://developer.mozilla.org/ja/docs/Glossary/Quality_values
Firefox では、上記の ja,en-US;q=0.7,en;q=0.3 という結果になりましたが、 Google Chrome , Microsoft Edge でも同じページを表示してテストしてみました。
Mozilla Firefox ファイヤーフォックス バージョン 61
["HTTP_ACCEPT_LANGUAGE"]=> string(23) "ja,en-US;q=0.7,en;q=0.3"
Google Chrome クローム バージョン 67
["HTTP_ACCEPT_LANGUAGE"]=> string(23) "ja,en-US;q=0.9,en;q=0.8"
Microsoft Edge エッジ バージョン 42
["HTTP_ACCEPT_LANGUAGE"]=> string(2) "ja"
結果、ブラウザによって、出力される言語名、重み付けの数値の組み合わせが違ってきました。 HTTP_ACCEPT_LANGUAGE の値は、各ウェブブラウザの初期設定と、おそらく、その後のユーザーの独自の言語設定によって異なるようです。
ということで、次は、ウェブブラウザの言語設定を見てみます。 Mozilla Firefox 限定になりますが、よければご覧下さい。
Firefox の言語設定
Firefox の言語設定の変更を試してみます。以下、 4 ステップありますが良ければご覧下さい。
Step.1
- Firefox の左上の、横棒 3 本のボタンをクリックします。このボタンのような見た目のものを、ハンバーガーメニューといういうらしいです。
- 「オプション」をクリックします。
Step.2
- 「一般」パネル、タブ?が表示されていると思います。
- 少し下のほうにある「言語設定」をクリックしてみます。
Step.3
そうすると「ウェブページの言語」の画面が表示されました。
- 日本語 [ja] 、英語(アメリカ合衆国) [en-us] 、英語 [en] と表示されていました。優先順で並んでいるようです。
補足ですが、この優先順位を en-us , ja , en と変更してみたところ、 $_SERVER ["HTTP_ACCEPT_LANGUAGE"] の結果が en-US,ja;q=0.7,en;q=0.3 になりました。 - 他の言語を追加できるようです。追加する場合は、クリックしてみます。
Step.4
- 言語名がリストで表示されました。今回は、言語を追加しないので、「キャンセル」で終了しました。
言語名で表示分岐
PHP で HTTP_ACCEPT_LANGUAGE の言語名を取得して、ウェブページの表示を分岐する方法を考えてみました。あまり参考にならないと思いますが、良ければご覧下さい。
HTTP_ACCEPT_LANGUAGE 値は、以下の内容だとします。
ja,en-US;q=0.7,en;q=0.3
PHP の strpos 関数を使用した分岐を試してみます。 strpos 関数は、指定文字の位置を検索できる関数のようです。
- PHP: strpos - Manual
- http://php.net/manual/ja/function.strpos.php
以下のようなソースコードを書いてみました。実行してみます。
PHP ソースコード:
<?php
if( array_key_exists( "HTTP_ACCEPT_LANGUAGE" , $_SERVER ) ){ //キーがある場合。
$hal = $_SERVER["HTTP_ACCEPT_LANGUAGE"]; //言語名を取得。 //ja,en-US;q=0.7,en;q=0.3 を返す。
$pos = strpos( $hal , "ja" ); //ja の位置を取得。 //0 を返す。 //先頭にある場合は 0 を返すようです。
//$pos2 = strpos( $hal , "ja," ); //使用しません。
//$pos3 = strpos( $hal , "ja;q=" ); //使用しません。
//strpos 関数が false を返したかどうかの判定は === または !== で厳密(というらしいです)に比較しないと、検索結果の位置が 0 の場合、 0==false で true と判定されてしまい、実際は指定の文字が 0 の開始位置で含まれているのに、含まれていない false として、誤判定してしまうことになるようです。
if( $pos !== false && $pos == 0 ){ //ja が含まれていて先頭の場合
echo "ja が最優先の言語設定。";
}
elseif( $pos !== false ){ //ja が含まれている場合
echo "ja が含まれる言語設定。";
}
else{ //その他の場合
echo "ja が含まれない言語設定。";
}
}
else{ //キーがない場合。
echo "HTTP_ACCEPT_LANGUAGE キーが存在しません。";
}
?>
結果を見てみます。
HTTP_ACCEPT_LANGUAGE が「ja,en-US;q=0.7,en;q=0.3」の場合は、以下の出力になりました。
ja が最優先の言語設定。
!ご注意ください
以下で Firefox の言語設定を変更していますが、全ての言語設定を削除した後に、言語を追加しようとすると、言語を追加後の「OK」の確定ボタンが押せない状態( OK ボタンがどこかに隠れてるのか表示されなくなる)になってしまいました。
私の場合は、 Tab キーを押したあとに Enter キーを押したことで「OK」ボタンを押したことになったようで良かったですが、 Firefox を再インストールしなければならないかもしれないのでご注意下さい。
Firefox の言語設定を en-US , ja , en の順番に変更して、再度実行してみます。そうすると、HTTP_ACCEPT_LANGUAGE が「en-US,ja;q=0.7,en;q=0.3」になり、以下の出力になりました。
ja が含まれる言語設定。
今度は、 Firefox の言語設定から日本語 ja を削除して、 en-US , en の順番に変更して実行してみます。そうすると、HTTP_ACCEPT_LANGUAGE が「en-US,en;q=0.5」になり、以下の出力になりました。 ja を削除しても、日本語のウェブページは日本語になっていました。
ja が含まれない言語設定。
次は、 Firefox の言語設定から全ての言語設定を削除して実行してみます。以下の出力になりました。
HTTP_ACCEPT_LANGUAGE キーが存在しません。
Firefox の言語設定を元に戻しておきましょう。
あとがき
今回、 HTTP_ACCEPT_LANGUAGE 値を取得して、ウェブブラウザの言語設定を判定後、ウェブページの分岐のテストを行ってみましたが、ウェブブラウザの言語設定で変化する値なので、これのみでは、正確な分岐は出来ないのかもしれません。ウェブサイト訪問者さんの、言語(国)の大体の判断など、覚えておくと何かの時に使用できそうです。
Firefox の言語設定で、追加できる言語の一覧を作成しようと思いましたが、数があるのでまたの機会に投稿できればと思います。
以上、閲覧ありがとうございました。
- [ Amazon.co.jp アソシエイト ] PHP 関係の本
- https://amzn.to/41Kpx4Q