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
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
Google Analytics APIを CakePHP3で動かしてレポートデータを取得する方法の解説
CakePHP3で Google Analytics APIからレポートデータを取得する処理の解説。PHPのサンプルソースをCakePHP3で動くように改造。加えて、ディメンションやメトリックスを条件に設定する方法なども。
-
CakePHP 2.3 連携先のテーブルの項目で条件抽出する場合
アソシエーション(連携)している先のテーブルの項目で条件抽出する際の考え方と注意点をサンプルソースを用いて説明しています。
-
CakePHP4から外部のデータベースにアクセスする方法解説
CakePHP4のシステムから他のシステムのデータベースにアクセスをし、SQL文を実行する方法を解説。try-catchでエラーを取得する方法も解説。
-
CakePHP3、CakePHP4のdatetime型カラムの日時の扱い。秒まで表示する方法
CakePHP3の日時カラムで秒まで扱う場合はdate()、strtotime()関数ではうまくいかない。CakePHP3であらかじめ用意された「i18nFormat()」を使用する。
-
CakePHP3の更新画面でUpload Plugin 3.0を使う方法、viewで使う方法解説・その3
CakePHP3でファイル、画像をアップロードするプラグイン、upload plugin 3を導入する手順を解説した記事。3部作のその3で記事を更新する際のファイルの取り回しなどについてを解説。
-
CakePHP4のCakeDC/Usersの Usersへの接続、バリデーションのカスタマイズ方法解説
CakeDC謹製Usersプラグインの紹介。CakePHP4で使う場合のUsersのカスタマイズとして入力項目のバリデーションの変更を、プラグインのファイルは触らずオーバーライドにより実装する方法を解説する。
-
CakePHP3のCakeDC/Usersのバリデーションのカスタマイズ方法解説
CakeDC謹製Usersプラグインの紹介。Usersのカスタマイズとして入力項目のバリデーションの変更を、プラグインのファイルは触らずオーバーライドにより実装する方法を解説する。
-
CakePHP3で値を入力直後にバリデーションする方法解説
CakePHP3でバリデーションの実行を保存する時から入力情報を受け取るときに変更する処理の解説。CakePHP3ではnewEntity()の処理でバリデートするため1行追加で対応可能。
-
CakePHP3でDocumentRootやtmp、webroot、logsなどのフォルダへのパスの定数
CakePHP3で特定フォルダのパスの定数を解説。root、DocumentRoot、app、config、webroot、tests、tmp、cache、vendor、コア、コアの srcが設定済み。realpath()関数を使うと柔軟なパス指定が可能。
-
CakePHP3のユーザ管理・ログイン認証プラグインCakeDC/Usersのインストール解説・3.6以降対応
CakePHP3のユーザ管理プラグイン Usersは、ユーザ登録、メール認証、ログイン認証、ユーザ管理、権限管理、reCAPTCHAなど会員制のサイトを簡単に実現可能。その導入方法、カスタマイズ方法を解説。