実用して感じたCakePHP2の良くないところ
calendar_today
2022-12-14
insights
views: 205
thumbnail images

はじめに

現在稼働中のシステムにCakePHP2が採用されているため、勉強がてら社内システムをCakePHPで作成してみようという話になり、CakePHPを実際に1週間以上じっくり触ってみた感想を書いてみる。

良くないところ

1. 配列!配列!配列!

とにかく配列が多すぎる。
ただでさえPHPは配列に一癖あるというのに(整数と文字列しか格納できないとか)、さらにその配列の悪い部分を存分に感じることが出来るフレームワークだと思った。
配列のせいで本来綺麗に整理出来るコードすら汚く見える。

例えば、Formヘルパー。
FormヘルパーはSelect以外で使う理由が分からない。

<?= $this->Form->input('User.name', ['type' => 'text', 'class' => 'form', 'autocomplete' => 'username']); ?>
<input name="User.name" type="text" class="form" autocomplete="username">

一行で書いてもヘルパーの方が長いのに、さらに配列が訳を分からなくしている。
訳が分からないので配列を改行すると、さらに汚くなるというジレンマに陥る。
本来間違いであればエラーが表示されたりするlintも効かなくなるし最悪だ。

<?= $this->Html->input('User.name', [
    'type' => 'text',
    'class' => 'form',
    'autocomplete' => 'username'
]); ?>

標準HTMLの方が直感的で、より綺麗に書ける。

モデルを取得した際の返り値も配列なのでundefined index祭りになること必至。

[
    [0] => [
        [Users] => [
            'id' => 1,
            'name' => 'foo bar',
        ],
        [Posts] => [
            'id' => 1,
            'title' => 'hoge',
            'content' => 'hugahuga',
        ],
    ],
    [1] => [
        [Users] => [...]
        [Posts] => []
    ]
]

さらにundefined indexを潰すためには isset()が必要になる。
ところがPHP5.7にはnull比較演算子がない。
ということは、全てのundefined indexを潰すには以下のような状態になる。

<tr>
    <td>
        <?= isset($user['name']) ? $user['name'] : '' ?>
    </td>
    <td>
        <?= isset($user['age']) ? $user['age'] : '' ?>
    </td>
</tr>

isset()祭りになる。

ちなみにLaravelでもPHP8以下では似たような問題があったが、こちらはオブジェクトで2階層以上下にアクセスする例だし、配列に比べればまだマシな方だろう。

<tr>
    <td>
        {{ optional($user->posts)->id ?? '' }} // PHP8未満
    </td>
    <td>
        {{ optional(optional($user->posts)->comments)->content ?? '' }} // 階層が増えるとoptional連続技になる
    </td>
    <td>
        {{ $user?->posts?->comments?->content ?? '' }} // PHP8のnull safe演算子で解決された
    </td>
</tr>

2. メソッドやヘルパー1つに機能を詰めすぎている

これも同じような理由だが、一つのメソッドに大量のデータを突っ込むように作られていると感じた。
例えばモデルを取得するfind()

$this->User->find('all', [
    'conditions' => [
        'User.id IN' => $id_list,
    ],
    'order' => 'User.last_login DESC',
    'limit' => 30,
]);

ひとつのfind()というメソッドに対して引数が2、第一引数には取得方法、第二引数の中には条件、並べ替え、リミットが指定されている。
これは配列地獄になる上に、渡す引数の型が間違っていた場合にエラーが表示されない。
例えば、limitに"abc"を渡してもコード上では問題ないように振る舞ってしまう。SQLクエリを投げて、初めてエラーが返ってくる。

せめてconditions, order, limitの3つだけでもメソッドチェーン出来るように設計してほしかったと思う。CakeBookのコーディング規約にはメソッドチェーンの記述があるのに。

3. コーディング規約に則っていない

基本的で重大な問題だと思う。
個人的に一番気になるのは、クラスの波括弧の改行の位置。

class User 
{
    public function create()
    {
        $user = new User();
    }
}

普通、PSR-2に則っているのならば上記のような記述方法だが、Cakeだと

class User {
    public function create() {
        $user = new User();
    }
}

このように最初の波括弧を改行しないよう指定がある。
またPSR-2ではタブは使用しないよう記載があるが、CakeBook2にはタブが指定されている。

まあ、フレームワークやプロジェクトごとに揃えるのが出来ていれば基本的には問題ないのだが、各言語のコーディング規約を読み漁る自分にとってはかなり違和感の感じるものだと思った。
バラバラのコーディング規約を揃えることにリソースが割かれることが一番厄介だと思う。

4. CakeBookがメチャクチャ見づらい

よく言われているが、CakeBookに色々ごちゃごちゃ文章が書かれていて見づらい。
その割に知りたいことが書かれていないこともザラだし、実際にどうやって使うのかコードが載っていないこともしばしばあり、これのせいで学習効率がとても落ちる。

反面、Laravelのドキュメントは公式の方も日本語翻訳版(Readouble)も簡潔に整理されていて、かつ情報量が多くてほしい情報にすぐたどり着ける。

最後に

たしかにCakePHP2はかなり古いフレームワークであることに変わりはないし、リリース当時のPHPバージョンも5とか4とか未成熟な状態であったろうから、上記の事が起こっても仕方がないのかなとは思う。比べているのも基本的にLaravelと比べているので。
ただメソッドチェーンにするとかの基本仕様は考えられたんじゃないかな....

触っていくうちに不満点がどんどん出てくるフレームワークも近年そうそうないなと思い、記事にしてみたというお話でした。

calendar_today
2022-12-14
insights
views: 205