Scaffoldがキモ可愛い「Livewire」をPHP 8.1.26＋Laravel 10.38.2で試してみた（ややモッサリ）

この記事は、[PHP Advent Calendar 2023 シリーズ1](https://qiita.com/advent-calendar/2023/python) の22日目です

昨日は、 @papillon さんで [「捕まえたWebシェルを調べてみる」](https://qiita.com/papillon/items/0ce9e940b4942e9f9747) でした

---

[piacere](https://twitter.com/piacere_ex) です、ご覧いただいてありがとございます :bow:

普段は、[Elixir／Phoenix／LiveView](https://qiita.com/advent-calendar/2023/elixir)メインで開発してますが、PHP開発は2000年頃から続けていて、年1～2本くらい既存システムのバージョンアップ案件やアセスメントをこなしていたりと、何かと触ってはいますが、PHPの新し目のWeb技術はあまり触れていません

そこで、前々から何となくは知ってたものの、ちゃんと触ったことが無かった「Livewire」について試してみたいと思います

Elixirにてサーバサイド主体のリアルタイムWeb／SPAを叶える「LiveView」と似た性質を持っていると言われるLiveWireなので、とても楽しみです

なお、LiveViewについては以前コラム書いていますので、良かったらご覧ください :information_desk_person_tone1:

https://qiita.com/piacerex/items/3f8ee18c9443d63955bf

Ruby on RailsのHotWireについてもコラム化しています

https://qiita.com/piacerex/items/b9cd99e2e051d24ce180

Python／DjangoのHotWireについてもコラム化しています

https://qiita.com/piacerex/items/bf2a32581579ab69f45b

あと、このコラムが、面白かったり、役に立ったら、![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/907a8695-4d83-1b5c-8052-d0ce52de5f66.png) をお願いします :bow:

# イントロダクション

「Livewire」のレポジトリは下記にあります

https://github.com/livewire/livewire

本家のサイトもあります

https://livewire.laravel.com

本家に「QuickStart」があるので、コレを試してみます（なお、本コラムはPHP 8.1.26＋Laravel 10.38.2での実施結果が書かれています）

**QuickStart**

https://livewire.laravel.com/docs/quickstart

# Prerequisites

Livewireの動作要件は、PHP 8.1以上＋Laravel 10以上のため、これらが入っていない方は、ここで入れておきましょう

それから、Laravel PJを作成し、起動します

```bash
composer create-project laravel/laravel livewire_tutorial
cd livewire_tutorial
php artisan serve
```

ブラウザで `http://localhost:8000` にアクセスすると、親の顔より良く見たLaravelデフォルトページが表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/67864bc0-fbe8-4811-fd91-51f7caa562b2.png)

# Install Livewire

Livewireをインストールします

```bash
composer require livewire/livewire
```

# Create a Livewire component

LivewireコンポーネントをScaffoldします

```bash
php artisan make:livewire counter
```

Scaffoldの実行結果がキモ可愛いw
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/6be26e1a-5784-b56e-0b8a-43e068e9cfcc.png)

`app` 配下と `resources/views` 配下にフォルダ／ファイルが追加されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/bdadddce-d76b-2466-1893-1dae1d966b39.png)

# Writing the class

Scaffoldで生成された下記に追記していきます

```diff_php:app/Livewire/Counter.php
<?php
 
namespace App\Livewire;
 
use Livewire\Component;
 
class Counter extends Component
{
+   public $count = 1;
+
+   public function increment()
+   {
+       $this->count++;
+   }
+
+   public function decrement()
+   {
+       $this->count--;
+   }
 
    public function render()
    {
        return view('livewire.counter');
    }
}
```

# Writing the view

Viewを追加します

```diff_php:resources/views/livewire/counter.blade.php
<div>
    <h1>{{ $count }}</h1>
 
    <button wire:click="increment">+</button>
 
    <button wire:click="decrement">-</button>
</div>
```

# Register a route for the component

routerに下記を追加します

```diff_php:routes/web.php
<?php

use Illuminate\Support\Facades\Route;
…
+use App\Livewire\Counter;
+
+Route::get('/counter', Counter::class);
```

# Create a template layout

LivewireのレイアウトをScaffoldします

```bash
php artisan livewire:layout
```

`resources/views` 配下にフォルダ／ファイルが追加されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/af913764-ffb5-47ed-df6a-1894afa80706.png)

作成された下記ファイル中、`{{ $slot }}` のところに、Livewireコンポーネントが出力されるようなので、これでScaffoldしたLivewireコンポーネントが使えるようになります

```diff_php:resources/views/components/layouts/app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
 
        <title>{{ $title ?? 'Page Title' }}</title>
    </head>
    <body>
        {{ $slot }}
    </body>
</html>
```

ブラウザで確認すると、動作がややモッサリな感じではありますが、ボタンクリックのたびにリロードせずカウントアップ／ダウンするSPAが出来ています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/9299c71c-ecb2-f6e1-ae87-614a8082dc62.png)

# 幾つか疑問

WebSocket相当が無いので、サーバサイドでのデータ変更を反映する仕組みは、果たしてあるんだろうか？

あと、RailsやPythonのHotWireは、明らかにSSRよりも軽量化されていたのに対し、Livewireはあまり軽量化された印象が無かった（ページ全体のリロードがされていないことは確認できたものの）ので、時間があれば原因究明したいところです

# 終わりに

PHPの「Livewire」を動かしてみました

RailsやPythonのHotWireよりも更にカンタンで、ElixirのLiveViewやReact、Vue.js、Svelteに近いイディオムでPHPサーバサイドSPAが開発できるのが魅力的です

一方で、プロダクションには適用しづいらいレベルに動作がモッサリな感じなのが気になります

とは言え、元々のLaravelのイディオムをあまり変えずに対応できる点は、RailsやPython同様、グッドな感じです

最後に余談ですが、実は現在、「PHP入門」と言うスキル判定が搭載されたElixir製プロダクト「Bright」を先日αリリースしています

https://bright-fun.org/

Brightは、過去／現在／未来のスキルから、あなたのBright（輝き）とRight（正しさ）を引き出すツールです

現在、下記がアンロックされています

- Elixir入門
- PHP入門
- Python入門
- React入門
- Webアプリ開発 Elixir
- PM（プロジェクトマネージャ）
- WebアプリUIデザイナー
- オウンドメディアマーケター

来年頭に下記がアンロック予定です

- チームリーダー／PL（プロジェクトリーダー）
- PdM（プロダクトマネージャ）
- 新人AWS or AWSプラクティショナー
- 新人Google Cloud or Google Cloudファンダメンタルズ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/6fabf1ea-ac07-7002-e660-a44ba416631c.png)

次期リリース（5月頃）で、「Webアプリ開発 PHP」もリリースするので、「Livewire」のスローダウンを攻略できたら、スキル科目に入れたいですね

---

明日は、@lyricrime さんで[「PHPの例外入門!」](https://qiita.com/lyricrime/items/63dd3a1c6053b45d96d7)です

# p.s.このコラムが、面白かったり、役に立ったら…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/907a8695-4d83-1b5c-8052-d0ce52de5f66.png) にて、どうぞ応援よろしくお願いします :bow: