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

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

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

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

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

2回答

4319閲覧

[cakePHP3] 多言語化対応 セレクトボックスより手動で設定する方法について

xjaPANDA

総合スコア124

PHP

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

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

1クリップ

投稿2016/07/22 17:32

CakePHP3の多言語化についての質問です。
やりたいことは、全ページのフッターに言語を選択するセレクトボックスを設置して、手動でも言語を変換できるようにしたいと考えています。

実装には、関数__()を利用して、src/localeフォルダを作成し、配下に、各言語フォルダとその中に、.poファイルと.moファイルを作成するやり方です。切り替えには、bootstrap.phpに、ini_set('intl.default_locale', 'ロケールID'); を 追加してページを変更したいと考えています。

とりあえず、よい方法かどうかはわからないのですが、
Template/Element に lang.ctpを作りそこに、下記のようなコードを追加しました。lang.ctpはLayout/default.phpより読み込まれ、すべてに適応します。要は、セレクトフォームよりpostで渡ってきた、ロケールIDをクッキーにセットして、bootstrap.phpのini_set('intl.default_locale', 'ロケールID')のロケールIDを変えようとしてます。

<?php if(filter_input(INPUT_POST, 'lang' )){ $lg = filter_input( INPUT_POST, "lang" ); setcookie( 'lang', $lg ); //クッキーにセット } $request_uri = filter_input(INPUT_SERVER, 'REQUEST_URI' ); //URIを取得 $param = ereg_replace('/?$', '', $request_uri); $params = array(); if ('' != $param) { $params = explode('/', $param); //切り分けて配列にいれる。 } if(!isset($params[3])||!isset($params[4])){ //私の環境では、コントローラーが[3]、アクションが[4]です。 $url_a = 'indexs'; //URIがない場合 ルートの時 $url_c = 'index'; // 〃 }else{ $url_a = $params[3]; $url_c = $params[4]; } ?> <section id="footer"> <div class="container"> <?=$this->Form->create(null,[ 'type' => 'post', 'url' => ['controller' => $url_a, 'action' => $url_c ]] ) ?> <?php $lang = filter_input(INPUT_COOKIE, 'lang' ); ?> <?=$this->Form->select( 'lang' , [ ['value'=> 'ja', 'text'=> 'Japanese' ] , ['value'=>'en_US', 'text'=> 'English' ] , ['value'=>'test', 'text'=> 'test'] , ],['default' => $lang]) ?> <?= $this->Form->button(__('Submit')) ?> <?= $this->Form->end() ?> </div> </section>

次に、config/bootstrap.phpに下記を追加して、各ページのセレクトボックスから保存されたクッキー情報(ロケールID)をセットしています。

$lang = filter_input(INPUT_COOKIE, 'lang' ); ini_set('intl.default_locale', $lang);

そこでわからないことが2つでてきました。

① 同一のコントローラー内のアクションでは、クッキーが保持され、セレクトボックスからのポストよりクッキー保存がうまくいくいきセレクトボックスで表示した言語で表示されるのですが、コントローラーが変わると、クッキーが、保持されず、どうやら次のコントローラーで別のクッキーが作られているので、コントローラーが変わるともう一度セレクトボックスで言語を指定しなくてはいけなくなります。

おそらく、setcookie()の部分のオプションがおかしいのだとおもったので、
下記のようにかいたのですが、サイト全体に共通するような形でクッキーが保持されません。

setcookie( 'lang', $lg, 0 , '/' );

どのように全体にでもクッキーを適応するのかがわかりません。

② サイトURLのルートからのアクセスだと、セレクトボックスで選択しても、クッキーに保存されません。なので、セレクトボックスが機能しないです。
URLのルートでは、もともとは、ルーティングでindexに設定した、コントローラーとアクション(私の場合、indexs/index)を設定しています。なのでURIが表示されないので、フォームからポストするときは、ポスト先をindexs/index になるようにしています。しかし、ルートへのアクセスからだとセレクトボックスでクッキーに保存できませんでした。

私自身、フレームワークを利用しはじめてから、1か月くらいなので、よくわかってない部分の方が多いので、どこにどのように書けばよいのかが、非効率になっていると思います。おそらく、もっと楽にできると思うので、手動で言語を変換する際に、もっとよい方法がありましたら、上記の回答以外にもアドバイスください。よろしくお願いします。

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

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

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

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

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

guest

回答2

0

ベストアンサー

CakePHP3でということなので、CakePHP3の機能を使った方法を紹介します。

言語の設定はAppControllerで切り替えるといいと思います。
AppControllerは基本的に全てのコントローラー共通の処理を行います。

PHP

1// AppController 2use Cake\Event\Event; 3use Cake\I18n\I18n; // I18n::locale()を使えるようにする 4 5public function initialize() 6{ 7 parent::initialize(); 8 $this->loadComponent('Cookie'); // クッキーコンポーネントを使う 9} 10 11// 他の処理を開始する前に、先に言語を設定する 12public function beforeFilter(Event $event) 13{ 14 if (!empty($this->Cookie->read('lang'))) { 15 I18n::locale($this->Cookie->read('lang')); // クッキーの値で言語を切り替える 16 } 17}

クッキーの値はクッキーの値を変更するためのコントローラー・アクションにPOSTして変更します。

PHP

1// POST先のコントローラー 2 3public function changeLanguage() 4{ 5 if (!$this->request->is(['post'])) return; // POSTのみ許可 6 7 $this->Cookie->write('lang', $this->request->data['lang']); // クッキーに言語をセット 8 return $this->redirect($this->referer()); // 元のURLへリダイレクト 9}

元のURLへ飛ぶ際にAppControllerの処理を通って言語を設定しているので、Kosuke_Shibuyaさんのおっしゃっている問題も起こらないはずです。

投稿2016/07/23 02:25

編集2016/07/23 02:30
coba-coba

総合スコア1409

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

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

xjaPANDA

2016/07/23 14:59

ありがとうございます。サンプルコードまで書いていただいたおかげで解決しました。クッキーコンポーネントがあったりすることは知りませんでした。また、コントローラーだけ呼び出すこともできるという使い方の発想がなかったので、同一ファイルにとりあえず書いてしまったのですが、まだまだよくわかっていないことだらけなので、とても感謝しています。
guest

0

前提となる知識として、
セッション -> サーバー
クッキー -> ブラウザ
にデータを保存する仕組みであることは、問題ないですね。

記述されたソースを簡略化すると、

php

1<?php 2setcookie( 'lang', $lg ); // 何らかの値をクッキーにセット 34filter_input(INPUT_COOKIE, 'lang' ); // クッキーから値を読み込む

これが、一つのファイルに書かれています。
このファイルが実行されている間には、セットから読み込みの間に、サーバーとブラウザの通信はありません。
クッキーに保存された値はブラウザからサーバーに送信されて初めてスクリプトで読み込みが可能になります。

ですので、set_cookie() されてから少なくとも一度はブラウザと通信がされない限り、$_COOKIES に値は設定されないので、取得もできません。

投稿2016/07/22 18:14

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

xjaPANDA

2016/07/23 14:54

ありがとうございます。クッキーの知識がほぼなかったので、非常に勉強になりました。同一ファイルに書かずにコントローラーに書いて解決しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問