久しぶりにPHPで開発(Laravel)をやることになったので感想

久しぶりにPHPで仕事をすることになったので、個人的なまとめ

## 直近の開発

- androidアプリ開発(kotlin)
- terraformを使ったRailsでの開発

数年前はPHPで開発していたが、当時は5.5とかだったような記憶
PHPもRailsも共に3年ぐらい
そんな人間が久しぶりにPHPで開発した日記だと思っていただければ…

## laravel

フレームワークは[Laravel - ウェブ職人のためのPHPフレームワーク](http://laravel.jp/) で開発
結構Railsだったらこうなのにみたいなことを思いながら開発していたので、その辺の不満が最初に結構ありました。
結果的に不満点が多くなってしまうかもしれませんが、フレームワーク自体はすごく使いやすいと思います。
Laravel歴は実質2ヶ月ぐらいなので、勘違いしている点はあるかもしれないがご了承ください。

### 開発用のライブラリを入れる

- [LaravelCollective/htm](https://github.com/LaravelCollective/html)  
- [Laravel Debugbar](https://github.com/barryvdh/laravel-debugbar)

この辺は鉄板だと思う。

- [laravel/telescope](https://github.com/laravel/telescope) も今度入れてみたい

### 開発中のログが出ない

開発中はターミナルで `tail -f storage/logs/laravel.log` を起動しっぱなしにしてログを表示させているけど、SQLやHTTP Requestのログが出ないのが非常に困ったので、とりあえずその辺は速攻直した

- [Laravelでhttpリクエストをlaravel.logに出力する - Qiita](https://qiita.com/tmf16/items/ee17878e17994458a498)
- [LaravelでSQL文をlaravel.logに出力する - Qiita](https://qiita.com/tmf16/items/f82c1af0d535b2337f61)

### バリデーション

[バリデーション 5.8 Laravel](https://readouble.com/laravel/5.8/ja/validation.html)

RailsでのModelバリデーションみたいなのが標準ではなくて、基本はControllerでの入力をバリデーションする
`laravel model validation` とかでググるといっぱい頑張ろうとした形跡があるからみんなmodelでバリデーションしたいんだろうなぁと思いながら一応公式に習ってControllerでバリデーションを入れていたが、細かいところで気に入らないところがあった

いわゆるCRUDで作ると新規作成と更新が別でできるがバリデーションは共通化したいので、以下のようなコードになる

```
    public function update(HogeRequest $request)
    public function store(HogeRequest $request)
```

ただ更新時にそのバリデーションだと動かないみたいなのがあって、例えばユニークの制限を入れたい場合はignoreしてあげないと
(DB的にユニークを入れるというのと別の条件の話）

```
class HogeRequest extends FormRequest
    public function rules()
    {
        $id = $this->input('id') ?? NULL;
        $hoge_id = $this->input('hoge_id');

        return [
            'name' => 'required|string',
            'hoge_id' => ['required','string','max:191',
                Rule::unique('hoges')->ignore($id)->where(function($query) use ($hoge_id) {
                    $query->where('hoge_id', $hoge_id);
                })
            ],
            'image'=> 'required_without:id|image',
        ];
```

こういうのがちょっと煩わしかった。
あと画像を含んだテーブルの場合に新規作成時は必須だが、更新時は無視したいみたいなのが細かくするのがうーんという感じ
Modelで保存or更新時に空っぽじゃないってかければなぁ…

## modelのイベントフック

やり方はいろいろあるみたいですが、自分は以下でやってます。

```
class Hoge extends Model
    protected static function boot()
    {
        parent::boot();
        static::saved(function($hoge)
        {
            self::savedListener($hoge);
        });
    }
```

いわゆるマスターデータみたいなモノをredis等にキャッシュさせて使うが、Modelの更新時にデータを消したいときに使います。　

```
    private static function savedListener(Hoge $hoge)
    {
        self::clearCache($hoge->id);
    }

    public static function clearCache($id)
    {
        Cache::forget('hoge' . $id);
    }
```


## Horizon

[Laravel Horizon](https://readouble.com/laravel/5.8/ja/horizon.html)

HorizonはRedisによるジョブ監視ツールという紹介がされているが、導入したのはキューを複数処理したかったので入れた
redisでしか動かないので、redisを指定する

```config/horizon.php

    'environments' => [
        'local' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['default'],
                'balance' => 'auto',
                'processes' => env('HORIZON_PROCESSES', 2),
                'tries' => 2,
            ],
        ],
    ],
```

http://localhost/horizon で監視画面が見えるが、デフォルトはlocalしか動かないので、本番や検証環境でも動かせるようにしたい場合は以下のリンクを参考にするとOK

[can not get Horizon dashboard authorization work](https://laracasts.com/discuss/channels/laravel/can-not-get-horizon-dashboard-authorization-work)

### ヘルパー

[ヘルパ 5.8 Laravel](https://readouble.com/laravel/5.8/ja/helpers.html)

たいして使ってないが、blank() と　filled()だけはめちゃくちゃ使った。


### Eloquent

[Eloquent：利用の開始 5.8 Laravel](https://readouble.com/laravel/5.8/ja/eloquent.html)

ORMとしてはRailsと同じ感覚で使えたからすんなり使えた。
ただ、findあるなら、findByも欲しかった。。。

`User::where('name', 'aaa')->get()->first();` みたいなの毎回書くのが普通なのかな…
この辺詳しい人教えて欲しいです。

### その他

- モデルのカラム名が欲しい
    - `$columns = Schema::getColumnListing('users');`
- 時間は `Carbon` を使う
- 画像をアップするのがすげーつらい。
- tinkerが `rails c`と同じで使いやすい
    - tinker上で `Hoge::find(1)->toSql();` ってやると実行されるSQLが出る
    - [A quick way to display a SQL query in tinker - Laravel Gems](http://laragems.com/post/a-quick-way-to-display-a-sql-query-in-tinker)
    - tinker上でコマンド打つとtoSqlなくても毎回実行されるSQLが表示されるのがちょっとだけ楽だった

---


最後まで読んでいただけた方がいらっしゃったら、以下の記事も参考になるかと思います。
[Rails 歴5年の僕が Laravel で開発するようになって思ったこと。｜Kurashicom Engineers' Blog｜note](https://note.mu/kurashicom_tech/n/n32ab25910783) 

## その他参考にしたサイト

- [Laravelのドキュメントはまぁ鉄板](https://readouble.com/laravel/5.8/ja/)
- [GitHub - alexeymezenin/laravel-best-practices: Laravel best practices](https://github.com/alexeymezenin/laravel-best-practices)
- [GitHub - chiraggude/awesome-laravel: A curated list of bookmarks, packages, tutorials, videos and other cool resources from the Laravel ecosystem](https://github.com/chiraggude/awesome-laravel)
- [20 Laravel Eloquent Tips and Tricks - Laravel News](https://laravel-news.com/eloquent-tips-tricks)