Laravel11で『PHPフレームワーク Laravel Webアプリケーション開発』差分メモ (第一部 Laravelの基礎 Chapter1)

# 概要
Laravel11で下記を写経した。
[PHPフレームワーク Laravel Webアプリケーション開発 バージョン8.x対応 (ソシム)](https://amzn.asia/d/dedpj7x)
今の設定と差分があるのでメモをしていく。

Laravelを触るのは4年ぶり。
最後触れたLaravelは6。

## 環境
* Laravel Framework 11.29.0
* Docker version 27.2.0
* Mac (intel)
* Laravel Sail (sail/runtimes/8.3)

(なお、`php artisan`コマンドについては、sailコマンドに慣れるのが微妙だったので、`sail shell`でコンテナの中に入って叩くようにしてます)

# 第一部 Laravelの基礎
## Chaper1 Laravelの概要
### RouteServiceProvider::HOMEがない

```
'/home'
```
みたいな文字列を作ってくれそうなのだが、そもそも
このHOME定数がもうLaravel11では無くなっている模様 [(参考)](https://zenn.dev/pcs_engineer/articles/laravel11-faq)。

```routes/web.php
Route::get('/home', function () {
    return view('home');
})->name('home');
```

名前をつけて、`'/home'`を作りたい時は、

```php
route('home');
```
で呼び出すようにして対処。

### SMTPサーバが MailHogではなく Mailpit
というだけ。
特に設定には困らない。

### app/Providers/EventServiceProvider.php がないし、Illuminate/Events/Registered.phpも無くなっている

リスナにイベントを登録するフェーズがあるが、
`EventServiceProvider`もなければ、`Registered`もない。[こちらの要領でやる感じらしい](https://readouble.com/laravel/11.x/ja/events.html)

#### `EventServiceProvider` の役割するのはどこへ行った...??
不要になったようです
> Laravelはデフォルトで、アプリケーションのListenersディレクトリをスキャンして、イベントリスナを自動的に見つけて登録します。handleまたは__invokeで始まるリスナクラスのメソッドが見つかると、Laravelはそれらのメソッドを、メソッドのシグネチャでタイプヒントしてあるイベントのイベントリスナとして登録します。

[Readouble Laravel 11.x イベント](https://readouble.com/laravel/11.x/ja/events.html)


#### Registeredクラスを自作する

`Registered`という名前は、汎用的すぎるから `UserRegistered`クラスとする

```linux
sail shell
php artisan make:event UserRegistered
```


```app/Events/UserRegistered.php
<?php

namespace App\Events;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use App\Models\User;

class UserRegistered
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    private User $user;

    /**
     * Create a new event instance.
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function getUser(): User
    {
        return $this->user;
    }
}
```

#### 作成したイベントをUser登録処理で受ける

```app/Http/Controllers/RegisterController.php
    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|confirmed|min:8',
        ]);

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        event(new UserRegistered($user));

        return view('regist.complete', compact('user'));
    }
```

### リスナーでイベントをリッスンする

```linux
php artisan make:listener SendWelcomeEmail --event=UserRegistered
```

この段階ではMail送信処理がリスナ内に書けないので、`SendWelcomeEmail` は一旦放置

### メール処理を書く準備をする
[Readouble 11.x メール Laravel](https://readouble.com/laravel/11.x/ja/mail.html)

```linux
php artisan make:mail WelcomeMail
```

#### メール送信のためのモジュールを準備

```app/Mail/WelcomeMail.php
<?php

namespace App\Mail;

use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Address;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class WelcomeMail extends Mailable
{
    use Queueable, SerializesModels;

    private User $user;

    /**
     * Create a new message instance.
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * Get the message envelope.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            from: new Address('xxxx.xxxx@xxxx.com', 'Developer'),
            subject: '会員登録メール',
        );
    }

    /**
     * Get the message content definition.
     */
    public function content(): Content
    {
        return new Content(
            view: 'emails.welcome',
            with: [
                'userName' => $this->user->name,
            ]
        );
    }

    /**
     * Get the attachments for the message.
     *
     * @return array<int, \Illuminate\Mail\Mailables\Attachment>
     */
    public function attachments(): array
    {
        return [];
    }
}

```

```resources/views/emails/welcome.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>会員登録メール</title>
</head>
<body>
    <h1>こんにちは, {{ $userName }}さん</h1>

    <p>会員登録完了しました</p>
</body>
</html>
```

### リスナーにメール処理を追記

```app/Listeners/SendWelcomeEmail.php
<?php

namespace App\Listeners;

use App\Events\UserRegistered;
use App\Mail\WelcomeMail;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Mail;

class SendWelcomeEmail
{
    /**
     * Create the event listener.
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     */
    public function handle(UserRegistered $event): void
    {
        // ユーザー登録時にウェルカムメールを送信
        Mail::to($event->getUser()->email)->send(new WelcomeMail($event->getUser()));
    }
}
```

### メール送信まで完了 !

![スクリーンショット 2024-10-30 11.15.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614597/a0d0c411-fe6e-4cc3-fc31-9a55e0f98e98.png)