ハウテレビジョン開発者ブログ

『外資就活ドットコム』を日夜開発している技術陣がプログラミングネタ・業務改善ネタ・よしなしごとについて記していきます。

CakePHPのarray地獄をHashクラスで生きのこる

CakePHPといえば array です。一挙手一投足にarrayがつきまとう、そんなCakePHPには、複雑な array を簡単に扱うために用意された Hash というユーティリティクラスがあります。

Hashクラスはこんな方々に有効です

  • キーの存在確認のために array_key_exists() や isset() を多用している
  • find した結果の array を望ましい形にするために、 foreach を回している
  • アソシエーションされたデータを取り出すために、 2重3重で foreach を回している
  • 気がつけばいつも foreach を回している

サンプルデータ

$results = array(
    0 => array(
        'Book' => array(
            'title' => 'ハッカーと画家',
            'auther' => 'Paul Graham',
            'Category' => array(
                0 => array(
                    'id' => 1,
                    'name' => 'コンピュータサイエンス'
                ),
                1 => array(
                    'id' => 3,
                    'name' => 'その他'
                )
            )
        )
    ),
    1 => array(
        'Book' => array(
            'title' => '秒速で1億円稼ぐ条件',
            'auther' => '与沢 翼',
            'Category' => array(
                0 => array(
                    'id' => 2,
                    'name' => 'ビジネス実用'
                )
            )
        )
    )
);

pathについて

Hashクラスでは $path と呼ばれる、配列内の任意の場所を指定するための構文を使います。 習うよりは慣れろ、例を見るほうが早いでしょう。

参考までに、パス構文の詳細はこちら http://book.cakephp.org/2.0/ja/core-utility-libraries/hash.html#hash-path-syntax

Hash::get(array $data, string $path)

Hash::get($results, '0.Book.title'); // ハッカーと画家
Hash::get($results, '1.Book.auther'); // 与沢翼
Hash::get($results, '0.Book.Category.1.name'); // その他
Hash::get($results, '1.Book.Category.1.name'); // null

存在しないパスを指定した場合は "エラーが出ず" nullが返ります。

//before
if (isset($results[0]['Book']['Category'][0]['name'])) {
    echo $results[0]['Book']['Category'][0]['name'];
}

//after
if ($name = Hash::get($results, '0.Book.Category.0.name')) {
    echo $name;
}

Hash::extract(array $data, string $path)

複雑な array から配列を作ることができます。

$books = Hash::extract($results, '{n}.Book.title');
pr($books);

/*
Array
(
    [0] => ハッカーと画家
    [1] => 秒速で1億円稼ぐ条件
)
*/

{n} は数値にマッチする独自の構文です。 詳しくは、公式ドキュメントにて。 http://book.cakephp.org/2.0/ja/core-utility-libraries/hash.html#hash-path-syntax

Hash::combine(array $data, string $path, string $path)

複雑な array から連想配列を作ることができます。 第二引数でキーを、第三引数で値を指定します。

Formヘルパーに渡す options を作る時などに重宝します。

$categories = Hash::combine($results, '{n}.Book.Category.{n}.id');
pr($categories);

/*
Array
(
    [1] => コンピュータサイエンス
    [3] => その他
    [2] => ビジネス実用
)
*/

その他メソッド

他にも、便利なメソッドが沢山あります。

詳しくは公式のドキュメントにて。 http://book.cakephp.org/2.0/ja/core-utility-libraries/hash.html