CakePHP3.8 と Laravel7.x の「書き方」の違い ~インストールとマイグレーション編~

# CakePHP3.8 と Laravel7.x の「書き方」の違い ~インストールとマイグレーション編~

CakePHPとLaravel よく速度や規約の違いと取り沙汰されることがありますが、書き方的な違いがまとまったものは見たことがないなーと思ってまとめてみます。
CakePHP のバージョンが若干ふるかったり、むしろ Laravel のバージョンが最新だったりするのは社内共有用のため(私事情)です。

前: ここが最初
次: [設定まわり](https://qiita.com/yokocho-comachi/items/7395faf51bd02da9dc76)

## インストール

同じ。

* CakePHP

```
composer create-project --prefer-dist cakephp/app:^3.8 {プロジェクト名}
```

* Laravel

```
composer create-project --prefer-dist laravel/laravel {プロジェクト名}
```

CakePHP3.8 は古いバージョンなので、バージョン指定をしています。
Cake も Laravel も create-project でインストールできるので同じ。

## マイグレーション

インストールしたらまずマイグレーションするんじゃないかなぁと思います。

### マイグレーションファイルの作成

Cake は `cake bake` コマンド、Laravel は `artisan make` コマンドを使ってマイグレーションファイルを作成します。

マイグレーションの実行は、Cake は `cake migrate` コマンド、Laravel は `artisan migrate` コマンドを使います。

* CakePHP

```
APP/bin/cake bake migration CreateUsers
```

* Laravel

```
php APP/artisan make:migration create_users
```

Cake:`Create{テーブル名}`、Laravel:`create_{テーブル名}`は特殊な接頭語で、このマイグレーションファイルでテーブルを作るよーという意味です。
ある程度マイグレーションファイルの中身を一緒に作ってくれます。

他にも、Cake:`Add{カラム名}To{テーブル名}` Laravel:`add_{カラム名}_to_{テーブル名}`など、決まった接頭語、接続語を使って名前を指定すると、ある程度までは中身を書いてくれます。

Cake はさらにコマンドの後ろに、`name:string[50] kana:string?`のような指定をすると、そこそこ詳細なマイグレーションファイルを作ってくれます。

詳細は [CakePHP 公式で](https://book.cakephp.org/migrations/2/ja/index.html#id3) 

### マイグレーションファイルの中身

Cake はテーブルに対してチェーン(一つ繋ぎ)で指定し、カラムは関数で一括設定をします。
Laravel はテーブルに対してはクロージャ単位で設定し、カラムに対してチェーンで指定します。

Cake

```php
$table = $this->table('flights');
$table->addColumn('movies', 'json', [
    'default' => 'JSON_ARRAY()',
    'null' => false,
])
    ->addColumn('created_at', 'datetime', [
        'default' => 'CURRENT_TIMESTAMP',
        'null' => false,
    ])
    ->addColumn('updated_at', 'datetime', [
        'default' => 'CURRENT_TIMESTAMP',
        'update' => 'CURRENT_TIMESTAMP',
        'null' => false,
    ])
    ->create();
```

Laravel

```php
Schema::create('flights', function (Blueprint $table) {
    $table->id();
    $table->json('movies')->default(new Expression('(JSON_ARRAY())'));
    $table->dateTime('created_at', 0)
        ->useCurrent();
    $table->dateTime('updated_at', 0)
        ->default(new Expression('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
});
```

Cake と Laravel それぞれできること(関数で用意されていること)が違うので、公式を見ると良いです。
双方、生のSQLを流すこともできるので、関数が用意されていなくてもSQLを直接書き込むことでカバーできます。

[Cake公式](https://book.cakephp.org/phinx/0/ja/migrations.html)
[Laravel日本語訳](https://readouble.com/laravel/7.x/ja/migrations.html)

### 実行

* マイグレーション実行  
Cake `APP/bin/cake migrations migrate`  
Laravel `php APP/artisan migrate`
* ロールバック実行  
Cake `APP/bin/cake migrations rollback`  
Laravel `php APP/artisan migrate:rollback`
* マイグレーション状況確認  
Cake `APP/bin/cake migrations status`  
Laravel `php APP/artisan migrate:status`
* 初期化(Laravel のみ)  
`php APP/artisan migrate:fresh`

## その他上で書けなかったことなど

個人的にはですが、Cake は自動でマイグレーションファイルを作ってくれるところまでが強くて、Laravel はマイグレーションでできることが強い印象です。

例えば Cake は実際のDBの差分からマイグレーションファイルを作成してくれる `APP/bin cake bake migration_diff` コマンドが標準でありますが、Laravel はプラグインをインストールしないとそういった機能はありません。

逆に、Laravel では tinyint メソッドが用意されていますが、Cake では tiny int 型は生のSQLを流さないとつくることができません。(int4 はできますが。)

## 終わりに

詳細は公式見比べるのが一番良いです。
次は Model 周りの保存を書くと思います。

前: ここが最初
次: Model(まだ)