CakePHP3のビューで受取ったテーブルのオブジェクトを連想配列に変換する方法
2019/07/22
ビューで受取ったテーブルのオブジェクトを連想配列に変換
オブジェクトを連想配列に変換する解説の前提
テーブルから取得したレコード情報(オブジェクト)を、コントローラーからビューに送ります。
その送ったオブジェクトを、ビュー内で連想配列として扱う方法について解説します。
「CakePHP3で他のテーブルのマスタテーブルからセレクトボックス(プルダウンリスト)を作る」の記事で利用したユーザテーブルと権限マスタテーブルを利用しています。
というか、「CakePHP3で他のテーブルのマスタテーブルからセレクトボックス(プルダウンリスト)を作る」の記事のあれこれ試す中で確認した内容になります。
やりたいことは、「UsersController.php」で取得した「権限マスタテーブル」のオブジェクトを、コントローラーからビューに送信し、ビュー側で「権限マスタ」にある「権限名(master_roles.name)」を、Usersの一覧表の「権限名」のところに編集する方法です。
そのため、ビューで受けとたオブジェクトを連想配列に変換する方法を必要としました。
コントローラーからビューに送る処理
「CakePHP3で他のテーブルのマスタテーブルからセレクトボックス(プルダウンリスト)を作る」のテーブル情報を見ながら確認してほしいのですが、下記の様に「UsersController.php」で権限マスタの情報を取得し、21行目の setで「$masterRoles」変数としてビューに渡しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?php namespace App\Controller; use App\Controller\AppController; use Cake\ORM\TableRegistry; /** * Users Controller * * @property \App\Model\Table\UsersTable $Users */ class UsersController extends AppController { public function initialize(){ parent::initialize(); $this->MasterRoles = TableRegistry::getTableLocator()->get("master_roles"); } public function beforeFilter(){ $this->set("masterRoles",$this->MasterRoles->find()->all()); } |
2019.07.22 追記
CakePHP3.6から、TableRegistryクラスの使用方法が変更になりました。
そのため、上記のサンプルコードも CakePHP3.6 以降の記述方法に変更しました。
1 2 3 4 5 |
// 3.6.0 以降 $articles = TableRegistry::getTableLocator()->get('Articles'); // 3.6.0 より前 $articles = TableRegistry::get('Articles'); |
ビューで受け取り foreach文で処理
ビュー側で受け取ったオブジェクトは、下記のようなに foreach文でグルグル回しながら値を取得していくことができます。
1 2 3 4 5 |
foreach ($masterRoles as $role){ $roleName = $role->name : : } |
ここまでは特に問題がありません。
問題点:オブジェクトのままでは個別の値が取得できない!
ですが、受け取った情報は「権限マスタ」ですので、foreach文でグルグル回しながら使うことはほぼなく、下記のように「0」の位置を指定して値を取得したいわけです。
1 |
echo $masterRoles[0]->name; |
ですが、コントローラーからビューに送られる値は、オブジェクトのため、こういう形式で受け取ることができないのです。
なので、いろいろ試してみました。
1 2 3 4 |
echo $masterRoles[0]->name; echo $masterRoles->0->name; echo $masterRoles[0]["name"]; echo ((array)$masterRoles)[0]->name; |
上記の記述方法ではいずれも「Error: Cannot use object of type Cake\ORM\ResultSet as array」というエラーになるのです。
最後の「((array)$masterRoles)[0]->name;
」という記述方法は、オブジェクトがネストしていなければ有効なようですが、テーブル情報として送られてくるオブジェクトはネストしていますので、うまく機能しません。
解決方法:オブジェクトを連想配列にするには toArray()を使う!
前置きが長くなりましたが、ようやく解決方法です。
ビューで受け取ったオブジェクトを連想配列に変換する方法です。
連想配列に変換できればいつものように連想配列の位置を指定して値を取得できるようになります。
下記の様にコントローラーから受け取ったオブジェクト「$masterRoles」を「toArray()」メソッドを使うことで連想配列に変換することができます。
1 2 3 4 5 |
$masterRolesArray = $masterRoles->toArray(); echo $masterRolesArray[0]->name; // 1行で書くことも可能 echo $masterRoles->toArray()[1]->name; |
連想配列に変換できれば、あとは普通の連想配列ですので、0番目のレコードを取得する場合は「$masterRolesArray[0]」と指定することで取得できるようになります。
ちなみに、「$masterRolesArray[0]」で取得した中身はまたオブジェクトなので、「name」を取得する場合は「$masterRolesArray[0]->name」となります。
オフィシャルサイトでは下記の「データのロードに Finder を使う」の中に書いてありました。
https://book.cakephp.org/3.0/ja/orm/retrieving-data-and-resultsets.html#finder
オブジェクトを連想配列に変換する方法のあとがき
この「toArray()」メソッドを知る前は、一度 foreach文でグルグル回して連想配列に置き換えるという処理をしていました。
今回は、Usersコントローラーから $masterRolesという他のテーブルの情報を読み込んだときの話ですが、マスタ情報を読み込んだときだけの話ではありません。
「http://example.com/Users」で見ることができる一覧ページでは、下記の様に「$users」を foreach文でグルグル回して一覧表を生成する処理があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php foreach ($users as $user): ?> <tr> <td><?= $this->Number->format($user->id) ?></td> <td><?= h($user->username) ?></td> <td><?= h($user->password) ?></td> <td><?= h($user->created) ?></td> <td><?= h($user->modified) ?></td> <td class="actions"> <?= $this->Html->link(__('View'), ['action' => 'view', $user->id]) ?> <?= $this->Html->link(__('Edit'), ['action' => 'edit', $user->id]) ?> <?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $user->id], ['confirm' => __('Are you sure you want to delete # {0}?', $user->id)]) ?> </td> </tr> <?php endforeach; ?> |
この Usersのページでも、一覧表を作るというのではなく、「『$users』のオブジェクトから 2件目のレコードの『username』を取得する」という場合も同じように「toArray()」メソッドを使うと連想配列になりますので、下記のような形で値の取得ができるようになります。
1 2 |
$usersArray = $users->toArray(); echo $usersArray[1]->username; |
まぁ、「toArray()」メソッドを記述するだけで連想配列になるとはいえ、オブジェクトの 2個目の値を使いたい、っていうような要望はよくあると思うので、わざわざ連想配列に変換しなくても利用できる方法があってもよさそうな気がするんですが...
他に方法はないんですかね?
ちなみに、下記のサイトを見る感じでは、PHP自体には「toArray()」メソッドはなさそうですね。
http://qiita.com/ymm1x/items/f197ddd327356b1e9088
CakePHP3の関連記事
CakePHP4のCSS、JavaScript、画像のブラウザへのキャッシュをコントロールするCakePHP3でレコードを保存(追加、更新、Insert、Update)する複数の方法を紹介
CakePHP3でモデルなしフォームからCSVをアップロードしレコードを更新する方法解説
CakePHP3でPHP Simple HTML DOM Parserを使ってスクレイピングする方法
CakePHP3のInsert On Duplicate Key Update(upsert)構文を解説・バルク処理も
CakePHP3の1対多での連携を中間テーブルを使った多対多の連携に変更するときの手順
CakePHP3でデフォルトのソート条件を設定してユーザの選択肢たソート条件を有効にする方法
CakePHP3で Ajaxを使う方法の解説。3.6以降対応。Successとthenの両方を解説。
CakePHP3でパンくずの指定は HTMLヘルパーを使って指定する方法を解説
CakePHP3にOGPをfetch、asignを利用してテンプレートごとに指定する方法を解説
その他の「CakePHP3」に関する記事一覧
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
CakePHP4の定数定義ファイルを環境変数によって本番と開発を振り分ける方法解説
CakePHP4で開発環境と本番環境とで違う設定ファイルを読み込ませて環境ごとに定数を切り替える方法を解説。Apacheのhttpd.confに環境変数を設定しそれを読み込み判別する。
-
CakePHP3、CakePHP4、CakePHP5のバージョンを指定してインストールする詳細な手順を解説
CakePHP3のバージョンを指定してインストールする方法を詳細解説。CakePHP3のインストールはComposerを使うため設定もほぼ自動で完了。データベースの接続情報を記載すればアプリ開発のベースが整う。
-
CakePHP 2.3 Search Pluginで検索処理 その7queryを使って 日付の範囲検索
CakePHPの検索プラグイン Search Pluginの検索処理の中で queryを使って日付の範囲検索の方法です。
-
CakePHPで同一テーブル内の値を比較する条件でレコードを取得する方法
CakePHPの同一テーブルにある項目の値を比較し条件に合致するレコードを取得する方法を解説。[”項目名”=>”値”]ではなく[”項目名 = 項目名”]と書くところがポイント。
-
CakePHP3のプラグイン「CakeDC/Users」を日本語化・翻訳ファイルもダウンロード可
CakePHP3のユーザ管理、ログイン認証プラグインである「CakeDC/Users」のメッセージを日本語にする手順の解説とともに、日本語の翻訳ファイルを提供。ファイルを設置すれば日本語になる!
-
CakePHP3の検索プラグイン「friendsofcake/search」の様々な検索の仕方の実装方法
CakePHP3で検索をするプラグイン「friendsofcake/search」の検索条件のカスタマイズ方法の解説。検索項目を増やしたり、以上、以下での検索や、チェックボックスによる検索の方法などを解説。
-
CakePHP 2.3 ID以外のカラムでアソシエーション(連携)をさせる場合
ID以外のカラムでアソシエーション(連携)させるための考え方とサンプルソースを用いての説明を行っています。
-
CakePHP3のHtmlHelperのLink設定のまとめ。mailto、URL、Root/Homeのリンクなども
CakePHP3でHtmlHelperを使ってリンクの設定をする方法のまとめ。基本形からURLを指定、class、id、targetを指定、mailtoのリンク、画像をアンカーに、JavaScriptのダイアログなどの解説。
-
CakePHP2の検索Plugin CakeDC/Searchで重複を省くgroup by(distinct)の実装方法
CakePHP2の検索プラグイン「CakeDC/Search」で、重複レコードを省くgroup by、distinctを使う方法についての解説。設定する場所はpaginatorの条件とするので、find()関数と同じ。
-
CakePHP3の1対多での連携を中間テーブルを使った多対多の連携に変更するときの手順
CakePHP3で「1対多」の連携を中間テーブルを利用した「多対多」の連携に変更するときの手順のまとめ。中間テーブルの設定やModelの変更などを間違いやすい箇所を指摘しながらの解説。