CakePHP3でResultSetやCollectionにしたデータを配列に変換する際、基本的にはtoArray()を使うことが多いと思うが、時としてtoList()を使っている箇所もある。果たして両者の違いは何なのか調べてみた。検証したCakePHPのバージョンは3.6.13。
toArray()はキーを保持し、toList()はキーを振り直す
結論から書くと、
- toArray():キーを保持した状態で配列を返す
- toList():キーを連番で振り直した状態で配列を返す
という違いがある。例えば
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<?php namespace App\Controller; use App\Controller\AppController; use Cake\View\View; use Cake\Collection\Collection; class ArticlesController extends AppController { public function initialize() { parent::initialize(); } /** * デバッグ */ public function index() { $data = [ 'a' => [ 'id' => 1, 'name' => 'hoge', ], 'b' => [ 'id' => 2, 'name' => 'hogehoge', ], 'c' => [ 'id' => 3, 'name' => 'fuga', ], 'd' => [ 'id' => 4, 'name' => 'fugafuga', ], ]; $collection = new Collection($data); pr($collection->toArray()); pr($collection->toList()); exit; } } |
というコードがあったとしよう。デバッグ結果は下記のようになる:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
// toArray(): Array ( [a] => Array ( [id] => 1 [name] => hoge ) [b] => Array ( [id] => 2 [name] => hogehoge ) [c] => Array ( [id] => 3 [name] => fuga ) [d] => Array ( [id] => 4 [name] => fugafuga ) ) //toList() Array ( [0] => Array ( [id] => 1 [name] => hoge ) [1] => Array ( [id] => 2 [name] => hogehoge ) [2] => Array ( [id] => 3 [name] => fuga ) [3] => Array ( [id] => 4 [name] => fugafuga ) ) |
toArray()とtoList()の使い分け
基本的にはtoArray()でほぼ事足りる。ORMからDBへselect文を投げた後にレコードをEntityとして変換して取得できるResultSetでは、そもそもキーが連番で生成されるため、toArray()でもtoList()でも結果は変わらない。簡単に再現すると下記になる:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
// ... $data = [ 0 => [ 'id' => 1, 'name' => 'hoge', ], 1 => [ 'id' => 2, 'name' => 'hogehoge', ], 2 => [ 'id' => 3, 'name' => 'fuga', ], 3 => [ 'id' => 4, 'name' => 'fugafuga', ], ]; $collection = new Collection($data); pr($collection->toArray()); pr($collection->toList()); exit; // toArray() Array ( [0] => Array ( [id] => 1 [name] => hoge ) [1] => Array ( [id] => 2 [name] => hogehoge ) [2] => Array ( [id] => 3 [name] => fuga ) [3] => Array ( [id] => 4 [name] => fugafuga ) ) // toList() Array ( [0] => Array ( [id] => 1 [name] => hoge ) [1] => Array ( [id] => 2 [name] => hogehoge ) [2] => Array ( [id] => 3 [name] => fuga ) [3] => Array ( [id] => 4 [name] => fugafuga ) ) |
だが、何らかのデータをCollectionに手動追加した時には挙動が変わる。例えば下記:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
// ... $data = [ [ 'id' => 1, 'name' => 'hoge', ], [ 'id' => 2, 'name' => 'hogehoge', ], [ 'id' => 3, 'name' => 'fuga', ], [ 'id' => 4, 'name' => 'fugafuga', ], ]; $collection = new Collection($data); $appendData = [ 'id' => 5, 'name' => 'hogefuga' ]; $collection = $collection->appendItem($appendData); // 第2引数でキー指定なし pr($collection->toArray()); pr($collection->toList()); exit; // toArray() Array ( [0] => Array // 先頭のitemが$appendDataで上書きされてしまう ( [id] => 5 [name] => hogefuga ) [1] => Array ( [id] => 2 [name] => hogehoge ) [2] => Array ( [id] => 3 [name] => fuga ) [3] => Array ( [id] => 4 [name] => fugafuga ) ) // toList() Array ( [0] => Array ( [id] => 1 [name] => hoge ) [1] => Array ( [id] => 2 [name] => hogehoge ) [2] => Array ( [id] => 3 [name] => fuga ) [3] => Array ( [id] => 4 [name] => fugafuga ) [4] => Array // 期待した通りに後方へ$appendDataが追加される ( [id] => 5 [name] => hogefuga ) ) |
この場合にはtoList()を使うのが適切だと分かる。
ただし、上記においてはappendItem()で第2引数に適切なキー番号を指定すればその限りではない:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
// ... $data = [ [ 'id' => 1, 'name' => 'hoge', ], [ 'id' => 2, 'name' => 'hogehoge', ], [ 'id' => 3, 'name' => 'fuga', ], [ 'id' => 4, 'name' => 'fugafuga', ], ]; $collection = new Collection($data); $appendData = [ 'id' => 5, 'name' => 'hogefuga' ]; $collection = $collection->appendItem($appendData, 4); // 第2引数で適切なキーを指定 pr($collection->toArray()); pr($collection->toList()); exit; // toArray() Array ( [0] => Array ( [id] => 1 [name] => hoge ) [1] => Array ( [id] => 2 [name] => hogehoge ) [2] => Array ( [id] => 3 [name] => fuga ) [3] => Array ( [id] => 4 [name] => fugafuga ) [4] => Array ( [id] => 5 [name] => hogefuga ) ) // toList() Array ( [0] => Array ( [id] => 1 [name] => hoge ) [1] => Array ( [id] => 2 [name] => hogehoge ) [2] => Array ( [id] => 3 [name] => fuga ) [3] => Array ( [id] => 4 [name] => fugafuga ) [4] => Array ( [id] => 5 [name] => hogefuga ) ) |
が、後から追加したデータのキーを直接指定する機会はあまり無いと思うので、結局はappendItem()もしくはprependItem()とtoList()の併用が最も活用頻度が高いと思われる。
参考)
https://book.cakephp.org/3/ja/core-libraries/collections.html#id12