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

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

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

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

Q&A

3回答

3768閲覧

CakePHP3のPaginator機能を使用した上で、検索条件がGETパラメータなどで見えないようにPOSTでの実装方法を教えていただきたいです。

hikaru1013

総合スコア12

PHP

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

0グッド

1クリップ

投稿2019/04/10 03:08

編集2019/04/10 03:36

PHP(CakePHP3.7.1)で商品の画像管理システムを作っています。
現在CakePHP3のPaginator機能を使用し商品画像一覧と検索機能を実装しているのですが、検索条件がGETパラメータで見えてしまう状態です。
今後アカウント管理機能も作成する予定で、メールアドレスなど個人情報が検索条件に含めれる想定なので、CakePHP3のPaginator機能を使用した上でGETパラメータなどで検索条件が見えない形で、検索を行った後に2ページ目に遷移しても検索条件が引き継がれたままで検索条件に該当するデータの2ページ目が正常に表示される実装方法を教えていただきたいです。

該当のソースコード

Template

<?= $this->Form->create(null, ['type'=>'get', 'url'=>['action'=>'index', $producttypeId]]) ?> <!-- 検索 --> <h4 class="function-name-color">・画像検索</h4> <div class="form-group input-group"> <span class="input-group-addon">キーワード</span> <?= $this->Form->input('keyword', ['type'=>'text', 'label'=>false, 'placeholder'=>'キーワード入力してください', 'class'=>'form-control', 'value'=>$keyword]) ?> <span class="input-group-addon">商品カテゴリ</span> <?= $this->Form->input('category_id', [ 'label'=>false, 'options'=>$categories, 'class'=>'form-control', 'templates' => ['inputContainer' => '{{content}}'], 'empty'=>'全てのカテゴリ', 'default'=>$categoryId, ]) ?> </div> <div class="text-center" style="margin-bottom:23px;"> <?= $this->Form->button(__('検索<i class="ti-search m-l-5"></i>'), ['id'=>'button', 'type'=>'submit', 'class'=>'btn btn-info p-l-20 p-r-20', 'div'=>false,'role'=>'button']) ?> </div> <?= $this->Form->end() ?>

Controller

/** * Index method * 初期表示・検索結果表示 */ public function index($producttypeId = null) { $this->loadModel('Categories'); $this->loadModel('Producttypes'); // 検索条件 $keyword = null; $categoryId = null; // 画像データ $materialData = null; if ($this->request->is('get')) { // 検索ファイル名 $keyword = $this->request->query('keyword'); // 検索カテゴリ $categoryId = $this->request->query('category_id'); } // 商品カテゴリプルダウンデータ取得 $categories = $this->Categories->find('list')->where(['producttype_id' => $producttypeId]); // 検索条件追加 $where_tmp = [];   if ($keyword) { $where_tmp += ['OR' => [ 'Items.name like' => '%'. $keyword. '%', 'Items.description like' => '%'. $keyword. '%'] ];   }   if ($categoryId) {     $where_tmp += ['Items.category_id' => $categoryId]; } // CakePHPページング機能 $this->paginate = [ 'contain'=>['Categories'], 'conditions'=>['Categories.producttype_id' => $producttypeId, $where_tmp], 'order' => ['Items.id DESC'], 'limit'=>30, ]; $materialData = $this->paginate($this->Items); $this->set(compact('producttypeId', 'categories', 'materialData', 'keyword', 'categoryId')); }

試したこと

GETではなくPOSTで実装してみたのですが、検索条件を入力し検索結果一覧表示後に2ページ目に遷移すると、検索条件がリセットされてしまい、検索をかけていない全件表示状態の2ページ目が表示されてしまいました。
その為、検索条件がPOSTされた際に検索条件をsessionで保持し、2ページ目に遷移した時にsessionに保持されている条件でデータ抽出するようにしてみたのですが、sessionに検索条件が保持されている場合は無条件に検索をかけてしまうため、メニューから「商品の画像管理システム」のリンクを押下した時の初期表示のときも、sessionに検索条件が保持されている場合は検索をかけてしまう動きとなってしまいます。
初期表示の時はsessionに保持さている検索条件を破棄しようとしたのですが、メニューのリンクが押下された時の初期表示なのかPaginator機能の進むや戻るのリンクが押下された時の表示なのかがController側で識別ができず、POSTでsessionを使用しての検索条件を保持する実装は断念しました。

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

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

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

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

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

guest

回答3

0

本質は GET がページネーションによるものか、それとも他から飛んできた初期表示なのか、を区別する方法があるかどうかです。
手順としては以下のようにすればすっきりするはずです(コントローラー内)

  1. POST か GET かを切り分ける $this->request->is('POST')
  2. POST ならパラメータを元に検索条件を設定する
  3. GET であれば、遷移元をチェックする $this->request->env('HTTP_REFERER')

3-1.
遷移元のURLが表示する予定のURLと一致しない(クエリーパラメータ部分を除いて)なら、セッション上から検索条件を取り除く
3-2.
セッションから検索条件を取り出して(3-1が動いた場合は検索条件がすべて未設定と同じになる)、検索条件を設定する
4. 検索条件(2もしくは3-2で決定している)をセッションに保存する

余談:検索条件を変更して飛んできた場合でも、ページネーションの情報も合わせて飛んでくる(クエリパラメータとして)ため、例えばある程度進んだページを表示しているときに検索条件を変えた結果、その検索条件ではそのページ番号まで到達しない場合、ページネーションで例外(NotFoundException)が発生します。

その場合はページ番号を1にしたURLを作って、そこにリダイレクトするとよいです。

PHP

1try { 2 $data= $this->paginate($data_all); 3} catch (Cake\Http\Exception\NotFoundException $ex) { 4 // 検索条件が変わったなどでページがない場合、ページを1にリセットして呼び直す 5 $redirect_url = preg_replace('/page=\d+/', 'page=1', $this->request->getUrl()); 6 $this->redirect($redirect_url); 7}

投稿2019/04/10 04:59

編集2019/04/10 05:12
tacsheaven

総合スコア13703

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

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

hikaru1013

2019/04/15 09:18 編集

ご回答ありがとうございます。遷移元のURL取得やページネーション例外時など参考になりました。 上記の処理だと他の機能から遷移してきた時は問題ないのですが、メニューから同じ機能のリンクを押下した際や、F5ボタンなどで画面を更新した際も検索条件を初期化したいと考えているのですが、何か良い方法はありますでしょうか。もしあればご教授願いたいです。
tacsheaven

2019/04/16 00:07

リンクであればクエリーパラメータに「強制的に検索条件を初期化する」ようなフラグを追加して飛ばせばよいのでは。(そのフラグがある場合は 4. の直前で検索条件をクリアする) F5 は画面の再読込なので、条件を同じにするのが筋だと思います。
guest

0

今後アカウント管理機能も作成する予定で、メールアドレスなど個人情報が検索条件に含めれる想定なので、

  • 検索条件をすべてフォームから指定するのであれば、それは見えて構わない情報です。
  • 「ユーザーに見せない検索条件を追加する」のであれば、それはサーバサイドで処理してしまって、クライアント側には一切関係させないのが適切です。

ということで、「検索条件をPOSTで伝える」という解決策自体が、この課題への対応手段としてはあまり適切でないかなと思います。

投稿2019/04/10 03:53

maisumakun

総合スコア145184

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

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

maisumakun

2019/04/10 03:54

そして、POSTするにしても、ブラウザ内の検証ツールなどを使えば簡単に見られますので、情報の秘匿にはなりません。
hikaru1013

2019/04/10 06:09 編集

個人的にですが、アカウント検索後にメールアドレスなどの個人的情報がGETパラメータにのったままのURLが履歴などで残ってしまうので気になってしまうので「検索条件をPOSTで伝える」以外の方法も含めて何か他に良い方法がないか、もう少し調べてみたいと思います。 丁寧なご回答で参考になりました。ありがとうございます。
guest

0

なにもパラメータを渡さずにパラメータに基づいた表示をおこなうというのは
論理破綻しています

ただしクライアントが所定のページから次のページに移ったときに
カレントページを覚えておくということは
セッション、クッキー、localStorageなどを利用すれば可能です

投稿2019/04/10 03:12

yambejp

総合スコア114837

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

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

hikaru1013

2019/04/10 03:23 編集

説明不足で申し訳ありません。 検索条件としてパラメータは渡すのですが、GETではなくPOSTなどで良い方法があればご教授願いたいです。 「試したこと」にも記載しているように検索条件が見えない且つ検索結果の2ページ目が正常に表示されるように、POSTで実装しsessionで検索条件を保持してみたのですが、sessionの検索条件を破棄するタイミングが識別できず断念したという感じです。
yambejp

2019/04/10 04:16

セッションが使えるならページや検索条件を保持していれば正しく挙動するはずです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問