Laravelをちょっと触ってみる

LaravelはSymfonyのコンポーネントを基に作られたPHPのMVCフレームワークです。

# プロジェクトの作成

Docker Desktopがインストールされているマシンであれば、プロジェクトを下記のコマンドで新規作成できます。

```bash:MacOSの場合
curl -s "https://laravel.build/laravel-app" | bash
```

数分かかりますが、無事にプロジェクトが作成できたので実行してみます。

```bash
cd laravel-app
./vendor/bin/sail up
```

`http://0.0.0.0/`にアクセスすると、Laravelのデフォルトページが表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/d921f200-6d66-3212-3281-3f5fc93ae00d.png)

`sail`(セイル)という馴染みのないコマンドを実行しましたが、これは開発コンテナを簡単に扱えるようにした軽量なCLIだそうです。`docker-compose.yml`ファイルはあるので、`docker compose up`コマンドでも起動できました。

# 設定構成

`php artisan about`コマンドでLaravelのバージョンやパッケージ情報を確認することができました。configの設定ファイルを全て確認しなくても概要が分かるのは嬉しいですね。
![php_artisan_aboutで概要.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/718eb216-07e6-b4cb-a4f6-231b09e25eb4.png)

また、詳細な設定値を調べるときは `php artisan config:show <対象>`を使います。例えば`php artisan config:show database`を実行してみます。
![database詳細設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/a529f888-b31d-07b7-3b22-747addd91a2c.png)

今度はキャッシュの詳細設定をみてみます。
`php artisan config:show cache`を実行してます。
![cache詳細設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/bd362889-3c3c-7f7b-9d00-7843b0da14ae.png)

# ディレクトリ構成

まずはMVCに限定して見てみる

```
.
├── app
│   ├── Http
│   │   └── Controllers
│   │      └── UserController.php
│   └── Models
│       └── User.php
└── resources
    └── views
        └── login.blade.php
```



# ルーティング

Webサイトは`web.php`に、APIは`api.php`に分けて書くようだ。`api.php`に書いたルーティングでは、URLに自動的に`/api`プレフィックスが付与される。
この設定は`app/Providers/RouteServiceProvider.php`で設定できる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134221/0699afe6-cd5b-0cd4-45e4-a6beffcdc2f7.png" alt="ルーティングのエクスプローラー" width="300" />

```sh:ルーティング一覧を出力するコマンド
./vendor/bin/sail artisan route:list
```

Larvelのルーティングの書き方

```php
Route::get('/user/profile', [UserController::class, 'index'])->name('profile');

Route::post('/user/login', [UserController::class, 'handleLogin'])->name('login.submit');
```

nameをつけておくと、Laravelの組み込み関数のrouteからURLを取得することができます。そのため、aタグのhref属性を指定したり、formのaction属性を指定する際に便利です。

```php
<a href="{{ route('profile') }}">プロフィール</a>

<form action="{{ route('login.submit') }}" method="POST" >
```

## ルートのグルーピング

`Route::prefix`や`Route::controller`でルートの設定が簡潔になります。

```php
Route::prefix('user')->group(function () {
    Route::controller(UserController::class)->group(function () {
          Route::get('/profile', 'index')->name('profile');
          Route::post('/login', 'handleLogin')->name('login.submit');
    });
});
```


# Form

```php:view
{{-- エラーメッセージ --}}
@if ($errors->any())
    @foreach($errors->all() as $error)
        @php
          echo $error;
        @endphp
    @endforeach
@endif

<form action="{{ route('login.submit') }}" method="POST" >
    @csrf
    <input name="email" type="text" />
    <input name="password" type="text" />
    <button type="submit">ログイン</button>
</form>
```

- `@php`は`<?php` と同義
- `@if`や`@foreach`など便利なディレクティブが用意されている
- `@csrf`を書いてトークンを発行することで保護できる

```php:controller
class UserController extends Controller {
    public function handleLogin(Request $request) {
        // dd($request->all());

        $request->validate([
            'email' => ['required', 'email'],
            'password' => ['required', 'min:8', 'max:20',]
        ]);
        
        return $request;
    }
}
```

`dd($request->all());`でリクエストの中身を確認できるの便利ですね。
モデルにバインドしてバリデーションもできると思うので調べる。