🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

CakePHP

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

Q&A

解決済

2回答

2027閲覧

CakePHP3 Componentで処理した内容を所定のctpページへ渡す方法がわかりません

Ryota.I

総合スコア22

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

CakePHP

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

0グッド

0クリップ

投稿2019/11/29 09:46

■■実現、確認したいこと■■
・CakePHP3のComponentで処理した内容(検索結果)を、
本来の検索用のコントローラ(IcesController/search())で処理した時と同じように、
取得した値を指定のctpページ(Ices/ranking.ctp)へ渡し、表示させたい
・上記のctpページへ渡すための記述をどのようにすればよいか確認したい

▽環境▽
AWS Cloud9:無料枠
MySQL:ver5.7.26
CakePHP:ver3.8.2
PHP:ver7.2.19

▽▽ここから質問の内容です▽▽
お世話になります。
以前よりCakePHP3で記事投稿サイトを作成しており、
検索機能を実装したコントローラ(IcesControllerのSearchアクション)とは
別のコントローラ(UsersControllerのAddアクション)にて、
検索実行後、検索結果の表示が出るようにしたいと考えています。

自身で調べたところ、Componentに記述することで別コントローラの
処理を実行できることはわかったため、
Componentファイル作成まで済ませた上で、
Componentの処理の最後で、debugをしたところ、
欲しいデータが取得できているところまではわかりました。

ただ、それを本来表示するビュー(Ices/ranking.ctp)へ渡すことが、
どうすればできるのか、わからずにいます。

▽以下、現状の記述しているコード内容です▽
■/src/Controller/IcesController.php(検索機能が記載が記載されている元の場所)

php

1public function search(){ 2 3 $this->autoLayout = false; 4 $manufacturer = isset($this->request->query['manufacturer']) ? $this->request->query['manufacturer'] : null; 5 $keyword = isset($this->request->query['keyword']) ? $this->request->query['keyword'] : null; 6 if($manufacturer || $keyword){ 7 8 $ices = $this->Ices->find('all'); 9 $ices 10 ->where(['Ices.manufacturer like' => "%$manufacturer%", 11 'OR' => [ 12 ['Ices.ice_fraver like' => "%$keyword%"], 13 ['Ices.ice_name like' => "%$keyword%"], 14 ['Ices.simple_comment like' => "%$keyword%"], 15 ['Ices.desc_comment like' => "%$keyword%"], 16 ['Ices.ice_fraver like' => "%$keyword%"], 17 ['Ices.ice_name like' => "%$keyword%"], 18 ['Ices.simple_comment like' => "%$keyword%"], 19 ['Comments.comment like' => "%$keyword%"] 20 ] 21 ]) 22 ->contain(['Users','Comments.Users']) 23 ->leftJoinWith('Comments') 24 ->leftJoinWith('Users') 25 ->select([ 26 'ic_r_rate' => '(Ices.repeat_rate + SUM(COALESCE(Comments.repeat_rate, 0))) / (1 + COUNT(Comments.repeat_rate))', 27 'ic_s_rate' => '(Ices.stock_rate + SUM(COALESCE(Comments.stock_rate,0))) / (1 + COUNT(Comments.stock_rate))', 28 'ic_comments'=> 'COUNT(Comments.comment)' 29 ]) 30 ->select([ 31 'ic_r_rate' => '(Ices.repeat_rate + SUM(COALESCE(Comments.repeat_rate, 0))) / (1 + COUNT(Comments.repeat_rate))', 32 'ic_s_rate' => '(Ices.stock_rate + SUM(COALESCE(Comments.stock_rate,0))) / (1 + COUNT(Comments.stock_rate))', 33 'ic_comments'=> 'COUNT(Comments.comment)' 34 ]) 35 ->group(['Ices.id']) 36 ->select($this->Ices) 37 ->order(['ic_r_rate' => 'DESC', 38 'ic_s_rate' => 'DESC']) 39 ->all(); 40 $this->set('manufacturer', $manufacturer); 41 $this->set('keyword', $keyword); 42 $this->set('ices', $this->paginate($ices)); 43 $this->render('ranking');//検索結果がrankingページに渡されます 44 } 45 }

■/src/Controller/UsersController.php(検索機能を実行したい別コントローラ)

php

1<?php 2namespace App\Controller; 3use Exception; 4use Cake\Http\Exception\NotFoundException; 5use Cake\ORM\TableRegistry; 6use App\Controller\AppController; 7 8class UsersController extends AppController 9{ 10 11 public function initialize() 12 { 13 parent::initialize(); 14 $this->loadModel('Comments'); 15 $this->loadModel('Ices'); 16 $this->loadComponent('Search');// コンポーネントの読み込み 17 $this->Ices = TableRegistry::get("Ices");// コンポーネントで使用する上布お 18 $this->Auth->allow(['add', 'login', 'logout']); 19 } 20 21  // 一部省略 22  public function add() 23 { 24 $user = $this->Users->newEntity(); 25 if ($this->request->is('post')) { 26 $user = $this->Users->patchEntity($user, $this->request->getData()); 27 if ($this->Users->save($user)) { 28 $this->Flash->success(__('The user has been saved.')); 29 30 return $this->redirect(['action' => 'index']); 31 } 32 $this->Flash->error(__('The user could not be saved. Please, try again.')); 33 } 34 $this->set(compact('user')); 35 36 //----ここから検索機能を使用するために追記した内容---- 37 if($this->request->query('manufacturer') or $this->request->query('keyword')){ 38 $this->Search->icessearch($this->request->query('manufacturer'),$this->request->query('keyword')); 39 40 $this->set('manufacturer', $manufacturer); 41 $this->set('keyword', $keyword); 42 $this->set('ices', $this->paginate($ices)); 43 $this->redirect('Ices/Search', 'keyword','manufacturer'); 44 }//----検索機能を使用するために追記した内容ここまで---- 45

■/src/Controller/Component/SearchComponent.php(自身で作成したComponentファイル)

php

1<?php 2 3namespace App\Controller\Component; 4use Cake\Controller\Component; 5use Cake\ORM\TableRegistry; 6use Cake\Datasource\ModelAwareTrait; 7class SearchComponent extends Component 8{ 9 protected $_defaultConfig = []; 10 use ModelAwareTrait; 11 12 public function icessearch($manufacturer, $keyword) 13 { 14 $this->autoLayout = false; 15 $this->loadModel('Ices'); 16 17 $manufacturer = isset($this->request->query['manufacturer']) ? $this->request->query['manufacturer'] : null; 18 $keyword = isset($this->request->query['keyword']) ? $this->request->query['keyword'] : null; 19 20 if($manufacturer || $keyword){ 21 $ices = $this->Ices->find('all'); 22 23 $ices 24 ->where(['Ices.manufacturer like' => "%$manufacturer%", 25 'OR' => [ 26 ['Ices.ice_fraver like' => "%$keyword%"], 27 ['Ices.ice_name like' => "%$keyword%"], 28 ['Ices.simple_comment like' => "%$keyword%"], 29 ['Ices.desc_comment like' => "%$keyword%"], 30 ['Ices.ice_fraver like' => "%$keyword%"], 31 ['Ices.ice_name like' => "%$keyword%"], 32 ['Ices.simple_comment like' => "%$keyword%"], 33 ['Comments.comment like' => "%$keyword%"] 34 ] 35 ]) 36 ->contain(['Users','Comments.Users']) 37 ->leftJoinWith('Comments') 38 ->leftJoinWith('Users') 39 ->select([ 40 'ic_r_rate' => '(Ices.repeat_rate + SUM(COALESCE(Comments.repeat_rate, 0))) / (1 + COUNT(Comments.repeat_rate))', 41 'ic_s_rate' => '(Ices.stock_rate + SUM(COALESCE(Comments.stock_rate,0))) / (1 + COUNT(Comments.stock_rate))', 42 'ic_comments'=> 'COUNT(Comments.comment)' 43 ]) 44 45 ->select([ 46 'ic_r_rate' => '(Ices.repeat_rate + SUM(COALESCE(Comments.repeat_rate, 0))) / (1 + COUNT(Comments.repeat_rate))', 47 'ic_s_rate' => '(Ices.stock_rate + SUM(COALESCE(Comments.stock_rate,0))) / (1 + COUNT(Comments.stock_rate))', 48 'ic_comments'=> 'COUNT(Comments.comment)' 49 ]) 50 51 ->group(['Ices.id']) 52 ->select($this->Ices) 53 ->order(['ic_r_rate' => 'DESC', 54 'ic_s_rate' => 'DESC']) 55 ->all(); 56 // debug($ices->all()); 57 // exit(); 58         //----ここでdebugをすると、希望の情報が取得できていました---- 59 } 60 } 61}

■↑の最後の部分でdebugした結果です

//---一部省略しています--- object(Cake\ORM\ResultSet) { 'items' => [ (int) 0 => object(App\Model\Entity\Ice) { 'ic_r_rate' => '1.0000', 'price_no_tax' => (int) 22, 'buy_year' => (int) 232, 'buy_month' => (int) 2, 'image_file' => '5ddcc00011cd1-jellyfish.jpg', 'created' => object(Cake\I18n\FrozenTime) { 'time' => '2019-11-26T15:02:40+09:00', 'timezone' => 'Asia/Tokyo', 'fixedNowTime' => false }, 'modified' => object(Cake\I18n\FrozenTime) { 'time' => '2019-11-26T15:53:47+09:00', 'timezone' => 'Asia/Tokyo', 'fixedNowTime' => false }, 'simple_comment' => '実験66', 'desc_comment' => '実験66', 'repeat_rate' => (int) 1, 'stock_rate' => (int) 1, 'image_file_path' => 'webroot/files/Ices/image_file/', 'image_file_size' => (int) 775702, 'comments' => [], 'user' => object(App\Model\Entity\User) { 'id' => (int) 1, 'nickname' => 'ryota', 'profiel_comment' => 'チョコミント系のアイスが好きでよく食べています。よろしくお願いします。', 'created' => object(Cake\I18n\FrozenTime) { 'time' => '2019-09-01T12:06:22+09:00', 'timezone' => 'Asia/Tokyo', 'fixedNowTime' => false }, 'modified' => object(Cake\I18n\FrozenTime) { 'time' => '2019-09-01T16:21:01+09:00', 'timezone' => 'Asia/Tokyo', 'fixedNowTime' => false }, '[new]' => false, '[accessible]' => [ 'email' => true, 'password' => true, 'nickname' => true, 'profiel_comment' => true, 'created' => true, 'modified' => true, 'ices' => true ], '[dirty]' => [], '[original]' => [], '[virtual]' => [], '[hasErrors]' => false, '[errors]' => [], '[invalid]' => [], '[repository]' => 'Users' }, '[new]' => false, '[accessible]' => [ 'user_id' => true, 'manufacturer' => true, 'ice_name' => true, 'repeat_rate' => true, 'stock_rate' => true, 'image_file_path' => true, 'image_file_size' => true ], '[dirty]' => [], '[original]' => [], '[virtual]' => [], '[hasErrors]' => false, '[errors]' => [], '[invalid]' => [], '[repository]' => 'Ices' } ] }

不足している情報があった際には、教えていただければ、随時追加いたします。
お手数をおかけしますが、どうぞご教示をお願いいたします。

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

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

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

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

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

guest

回答2

0

コンポーネントの中で、 $this->getController() とすれば、呼び出し元のコントローラーが取得できます。
(古いバージョンでは $this->_registry->getController()

あとは、取得したコントローラーのsetに渡せばよいですね

追記

$this->getController() の戻り値が呼び出し元のコントローラーとなります。

なので、

php

1class SearchComponent extends Component 2{ 3 public function icesearch() 4 { 5 // なんやらかんやらの処理 6 7 $controller = $this->getController(); // ← コントローラーを取得して 8 $controller->set('ices', $ices); // ← $ices を View変数に渡す 9 } 10} 11

といった感じに書きます。

投稿2019/11/29 12:04

編集2019/12/02 11:20
nojimage

総合スコア959

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

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

Ryota.I

2019/11/30 07:58 編集

nojimage様 いつもお返事ありがとうございます。 昨晩より、いただいた内容を元に改めて$this->getController()の概要確認し、Componentに設置しました。加えて取得したコントローラのsetに渡すことについても、 調べてみたものの、現時点で希望する処理が実現できていない状況です。 下記のコードでの過不足な点、改良点を改めて教えていただけると助かります。 -------- ▽SerchComponentの追記箇所(※がついた部分が追記部分です)▽ <?php namespace App\Controller\Component; use App\Controller\AppController; use Cake\Controller\Component; use Cake\ORM\TableRegistry; use Cake\Datasource\ModelAwareTrait; class SearchComponent extends Component{ ※public function initialize($search) { ※ $this->getController(); ※ $this->Search = $search; } protected $_defaultConfig = []; use ModelAwareTrait;   ~同Component内の検索機能の下側「->all();」のすぐ下~ 【変更前】 $this->set('manufacturer', $manufacturer); $this->set('keyword', $keyword); $this->set('ices', $this->paginate($ices)); $this->render('ranking'); 【変更後】 $this->Search->set('manufacturer', $manufacturer); $this->Search->set('keyword', $keyword); $this->Search->set('ices', $this->paginate($ices)); $this->Search->render('ranking'); -------- ▽Userscontrollerの変更点▽ 【変更前】 //----ここから検索機能を使用するために追記した内容---- if($this->request->query('manufacturer') or $this->request->query('keyword')){ $this->Search->icessearch($this->request->query('manufacturer'),$this->request->query('keyword')); $this->set('manufacturer', $manufacturer); $this->set('keyword', $keyword); $this->set('ices', $this->paginate($ices)); $this->redirect('Ices/Search', 'keyword','manufacturer'); }//----検索機能を使用するために追記した内容ここまで---- 【変更後】 if($this->request->query('manufacturer') or $this->request->query('keyword')){ $this->Search = $this -> loadComponent('Search'); $manufacturer = $this->request->query('manufacturer'); $keyword = $this->request->query('keyword'); $this->Search->icessearch('$keyword','$manufacturer'); } 現状、いくつか試した上で、 結果的に2点の挙動が返ってきます。 1、Componentの->all();以下のset、renderメソッド部分は コメントアウトの上、検索を実行すると、 Userのaddコントローラの画面のままとなります。 ⇒この結果から今の自分の判断では、 Component側に何らかの記述が必要なのだな..という認識に至っています。 2、↑の1のsetやrenderはコメントアウトせず、検索実行してみると、 「Call to a member function set() on array」というエラーが 返ってきます。 ※丁度$this->Search->set('manufacturer', $manufacturer);の行を示しています。 ⇒この結果から、記述のミスがあることはわかりました。 上記の結果から、どのように記載内容を変更していけばよいか、 模索中の状況です。たびたびお手数ですが、お力添えをお願いいたします。
guest

0

自己解決

今回いただいたご返答の内容を踏まえ、少しずつ処理ができていないところを確認し、突き詰めつつありましたが、現状、Componentの設定を設けた上での処理ではなく、各コントローラのinitialize()内に、Ices/Search()の内容を記載することで、解決に至りました。希望する結果は得られたものの、現時点までComponentの利用方法を理解しきれていないため、引き続き自身で調べていきます。

今回投稿した質問については、希望する表示結果は得られたため、解決済み、とさせていただきます。
お返事いただけたnojimage様、あわせて質問内容に少しでも目を通していただけた方、ありがとうございました。

また別の質問を投稿させていただく際には、引き続きよろしくお願いいたします。

投稿2019/12/01 09:52

Ryota.I

総合スコア22

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

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

nojimage

2019/12/02 11:22

initializeは、コントローラーで使用するオブジェクトを初期化するところなので、取得処理を書く場所としては適していません。共通の表示用値をセットしたいのならbeforeRenderがふさわしいでしょう。
Ryota.I

2019/12/02 12:30

initializeの概要に加え、beforeRenderについても教えていただきありがとうございます。 「追記」いただいた内容もすぐに、とはいえませんがしっかりと消化し、使用できるようにします。 不明点があった際には改めて、質問させていただきますので、よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問