質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

2050閲覧

アクセス元の言語設定によってURLを振り分けるPHPのコードがうまく機能しない

tomaa

総合スコア84

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/03/17 13:49

編集2020/03/18 12:20

海外からのアクセスを、PHPのコードを利用して使用するURLを振り分けるようにしたいのですが、うまく動作しません。

  • A:sample.com
  • B:sample.com/en

2つのURLを用意し、最初のアクセスに利用するドメインは、Aのsample.comのみで、アクセス元やブラウザーの条件によって、A、Bへアクセスが変わるようにしたいです。

どのような、コードに修正すれば良いかご教授いただけないでしょうか?


追記②
オリジナルのサンプルコードに近い形で修正しましたが、こちらでも無限ループのエラーとなります。

$uri = $_SERVER['REQUEST_URI']; $BASE_LANG = 'en'; if (!preg_match('/^[!-~][a-zA-Z]{2}[!-~]/', $uri)) { $languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); $lang = $BASE_LANG; if (isset($languages)) { $browser_lamguage = $languages[0]; $base_languages = array('ja', 'en'); foreach ($base_languages as $base_language) { if (preg_match("/^$base_language/i", $browser_lamguage)) { $lang = $base_language; break; } } } $url = get_site_url()."/$lang/"; if ($lang == 'ja') { $url = get_site_url(); } header("Location: $url"); exit(); }

追記①
下記にこれまで試したコードを記載していますが、こちらのコード⑤が、最も希望に近い動きになるので、こちらのコードを変更して対応したいと思っています。

下記のようにコードを編集しましたが、ブラウザでアクセスした際にエラーがでます。
This page isn’t working
sample.com redirected you too many times.
Try clearing your cookies.
ERR_TOO_MANY_REDIRECTS

該当のソースコード

functions.phpに追加したコードは以下のとおりです。

// ユーザーの言語に合わせてリダイレクトする。 $uri = $_SERVER['REQUEST_URI']; $url = get_site_url(); //無限ループが起こらないようにするために、/と/en/にマッチしないときのみに以下の処理を行う if ($uri != '/' || $uri != '/en') { $languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); if (isset($languages)) { //languagesが空ではないとき $browser_lamguage = $languages[0]; if ($browser_lamguage != 'ja') { $url = get_site_url()."/en/"; } } header("Location: $url"); exit(); }

コード⑤
参考サイト:ブラウザのロケールを判別してlocaleを含むURLにリダイレクトさせる[PHP]
結果:
日本語設定でアクセス → sample.com/ja/へ、リダイレクト(404エラーとなる)
英語設定でアクセス → sample.com/en/へ、リダイレクト

オリジナルのコード

// ユーザーの言語に合わせてリダイレクトする。 $uri = $_SERVER["REQUEST_URI"]; $BASE_LANG = "en"; //無限ループが起こらないようにするために、/ja/や/en/にマッチしないときのみに以下の処理を行う if(!preg_match("/^[!-~][a-zA-Z]{2}[!-~]/",$uri)){ $languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); $lang = $BASE_LANG; if(isset($languages)){ //languagesが空ではないとき $browser_lamguage = $languages[0]; $base_languages = array('ja','en'); foreach($base_languages as $base_language){ if(preg_match("/^$base_language/i", $browser_lamguage)){ $lang = $base_language; break; } } } $url = get_site_url()."/$lang/"; header("Location: $url"); exit(); }

コード①
参考サイト:①日本語と、②日本語以外の、2つの条件で振り分けるPHPのコードを知りたい
結果:
日本語設定でアクセス → A:sample.comで表示される
英語設定でアクセス → B:sample.com/enに、リダイレクトされるが、ブラウザで無限ループのエラーとなる

コード②
参考サイト:海外からのアクセスを振り分ける[php]
結果:
日本語設定でアクセス → A:sample.comで表示される
英語設定でアクセス → B:sample.comで表示される(リダイレクトされない)

コード③
参考サイト:WordPressで多言語サイトを作成し、言語設定によってページをリダイレクトさせる
結果:
日本語設定でアクセス → ブラウザに、[サイトに重大なエラーがありました。]と表示される
英語設定でアクセス → ブラウザに、[サイトに重大なエラーがありました。]と表示される

コード④
参考サイト:【PHP】ブラウザの言語設定ごとに異なるURLにジャンプさせる方法
結果:
日本語設定でアクセス → ブラウザに、[サイトに重大なエラーがありました。]と表示される
英語設定でアクセス → ブラウザに、[サイトに重大なエラーがありました。]と表示される

もともとは、下に紹介している②のコードを改良して利用したく、teratailの他のページで質問でさせてもらっていましたが、改良する前でもうまく動かない事がわかり、今回の新しい質問として出させてもらっています。

②のコードに加えこれまで、以下のコードで試しましたがどれもうまく動作してくれません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/03/17 13:49

前回WordPressをタグにつけられてましたが、結局WordPressは関係ないのでしょうか。
tomaa

2020/03/17 13:52

最終的には、wordpressのマルチサイトで使用したいですが、現在の不具合はPHPの範囲で収まると考えられますので、タグを外しました。
退会済みユーザー

退会済みユーザー

2020/03/17 14:04

> *PHP言語の経験はなく、必要な箇所のみ変更して、サンプルコードをほぼコピペする形で使用したいと考えています。 くれくれくんは非推奨行為と利用規約にあるのでもらえないと思った方がいいよ
m.ts10806

2020/03/17 14:31 編集

WordPressで構築してるならWordPressの仕組み取り入れてやってかないと PurePHPから簡単に移管できるもんじゃないですよ。それだけWordPressって内部的にはPHPで作られていても特殊です。 ※それに既に指摘があるように理解する気がない前提の質問(というより作業依頼)に応じる人ってそうそういないですし。 「PHP言語の経験はなく」と自ら前置きしている人が「PHPの範囲で収まる」と判断できるようには思えません。
tomaa

2020/03/17 14:43

コメントありがとうございます。 一つのURLを、アクセスの条件によって振り分けるという動きを、wordpressのプラグインで対応できれば、一番良いのですが、調べてみてもその方法がわからなかったので、PHPのコードで対応する方法で対応したいと思っています。 自分で調べられる事は調べますし、解決につながる情報もらえればありがたいです。
guest

回答1

0

ベストアンサー

https://example.com/ にアクセスしたとき、
・英語なら /en/ へリダイレクト
・日本語ならそのまま
https://example.com/en/ にアクセスしたとき、
・英語ならそのまま
・日本語なら / へリダイレクト

これ↑をそのままコードにしました。

php

1 $uri = $_SERVER["REQUEST_URI"]; 2 $BASE_LANG = "en"; 3 $languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); 4 $lang = $BASE_LANG; 5 if(isset($languages)){ //languagesが空ではないとき 6 $browser_lamguage = $languages[0]; 7 $base_languages = array('ja','en'); 8 9 foreach($base_languages as $base_language){ 10 if(preg_match("/^$base_language/i", $browser_lamguage)){ 11 $lang = $base_language; 12 break; 13 } 14 } 15 } 16 17 if ($uri == '/' && $lang == 'en') { 18 $url = get_site_url()."/$lang/"; 19 header("Location: $url"); 20 exit; 21 } else if ($uri == '/en/' && $lang == 'ja') { 22 $url = get_site_url()."/"; 23 header("Location: $url"); 24 exit; 25 }

これ↓必ずTrueになりますよ。この条件でFalseになることはありませんね。

OR(||)じゃなくAND(&&)ですよね?

php

1 if ($uri != '/' || $uri != '/en') {
$uri$uri != '/'$uri != '/en'OR結果
/hogeTrueTrueTrue
/FalseTrueTrue
/enTrueFalseTrue

投稿2020/03/18 08:24

編集2020/03/18 12:16
Y.H.

総合スコア7918

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tomaa

2020/03/18 08:48 編集

ご回答していただきありがとうございます。 OR(||)→AND(&&)で試しました。 無限ループはしなくなりましたが、日本語でも、英語の設定でもどちらも、sample.comへのアクセスとなります。 質問に追記しましたが、オリジナルに近いコードで修正しましたが、こちらは無限ループとなってしまいます。
Y.H.

2020/03/18 09:07

そりゃ / へアクセスしたならif文でFalseになるから。 いろいろ質問たてていろいろ書かれてますが、 結局やりたいことは https://example.com/ にアクセスしたとき、  ・英語なら /en へリダイレクト  ・日本語ならそのまま https://example.com/en にアクセスしたとき、  ・英語ならそのまま  ・日本語なら / へリダイレクト ですか?
tomaa

2020/03/18 09:36

https://example.com/ にアクセスしたとき、  ・英語なら /en へリダイレクト  ・日本語ならそのまま https://example.com/en にアクセスしたとき、  ・英語でも日本語でもそのまま という内容にしたいです。
tomaa

2020/03/18 09:44

追記していただきありがとうございます。 新しいコードを試してみました。 https://example.com/ にアクセスすると、日本語でも英語でも、リダイレクトされずにそのままアクセスされます。
Y.H.

2020/03/18 09:51 編集

$uri = $_SERVER["REQUEST_URI"]; は回答には書いてませんが消してませんよね? 一応回答のコードに追加しておきました。
tomaa

2020/03/18 09:54

消していましたので、$uri = $_SERVER["REQUEST_URI"];を加えて(最新編集のコード)で行いましたが、こちらも、 https://example.com/ にアクセスすると、日本語でも英語でも、リダイレクトされずにそのままアクセスされます。
Y.H.

2020/03/18 10:12 編集

では、 $_SERVER['HTTP_ACCEPT_LANGUAGE'] には何が入ってますか? enまたはjaが入ってないのでは?
tomaa

2020/03/18 10:25

$languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); print_r($languages); で確認しました。 日本語の場合: Array([0]=>ja[1]=>en:q=0.9) 英語の場合: Array([0]=>en[1]=>ja:q=0.9) と表示されます。
Y.H.

2020/03/18 10:33

$_SERVER["REQUEST_URI"]も内容確認できますか?
tomaa

2020/03/18 10:39

print_r($_SERVER["REQUEST_URI"]); で確認しました。 日本語の場合、英語の場合どちらも / と表示されます。
Y.H.

2020/03/18 11:39

ではあとは$langだけですね。 if文の直前で確認してください。
tomaa

2020/03/18 11:47

$uri = $_SERVER["REQUEST_URI"]; $BASE_LANG = "en"; $languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); $lang = $BASE_LANG; print_r($lang); で確認しました。 日本語の場合、英語の場合どちらも en と表示されます。
Y.H.

2020/03/18 11:57

> 日本語の場合、英語の場合どちらも > en ということは↓を通ってないですね。 > $lang = $base_language; また、header()の次の行にexit;を入れてみてください。
Y.H.

2020/03/18 12:06

>$lang = $BASE_LANG; >print_r($lang); >で確認しました。 if ($uri == '/' && $lang == 'en') { の直前で確認してください。
tomaa

2020/03/18 12:10

>header()の次の行にexit;を入れてみてください。 を行ったところ、期待どおりの動きになりました。 大変参考になりました。大変助かりました。 長時間にわたりありがとうございます。
Y.H.

2020/03/18 12:14

解決して良かったです!
tomaa

2020/03/18 12:17

頼ってばかりで、すみませんでした。。。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問