これからLaravelを使ってみたい人へ
LaravelはPHPフレームワークとして抜群の知名度と実績があります。
MVCフレームワークの採用、Symfonyを基盤とした堅牢性、ORMの導入、Bladeテンプレートエンジンによる可読性の高いビューの実現など、便利な機能満載のフレームワークですが、何より他のPHPフレームワークに比べて群を抜いてユーザーが多いことで、つまずいた時にもQiitaなどですぐ調べられるという点が初心者にはうれしいところです。
この記事は、2020年9月にリリースされた Laravel 8 でサクッと社員管理システムを作ってみようという内容になっています。
最新のログイン認証機能のJetStreamもさりげなく使っちゃいます。
環境(以下のOS、並びにソフトがインストール済みの前提)
- Windows 10
- PHP実行環境 >= 7.3
- SQLite >= 3(なくても動くっちゃ動きます)
- Composer
- node.js
- Visual Studio Code
プロジェクトの全体像
1. MVCパターン
2.画面設計
3.実装機能
CRUD操作
ログイン機能
セキュリティ対策
入力チェック
ログ出力機能
プロジェクトを作成
プロジェクトフォルダが作成され、何やらいろいろダウンロードされます(5分位かかるかも)
これで準備は完了です
以降はここのターミナルからコマンドを実行しながら開発をしていきます
プログラムの作成
1. アプリケーションを実行する
プロジェクトはアプリケーションに必要なファイル類を一式そろえています。Laravelに内蔵されたWebサーバー機能を使うことで、アプリケーションを実行することが出来ます。
php artisan serve
と実行してこんな表示が出れば成功です。ローカルサーバーが立ち上がっています。
※補足ですが、Laravelでは php artisan コマンド [引数]
というコマンドを実行することで、Laravel独自のスクリプトファイルを作成したり、サーバーを実行したりといった便利な操作ができます。
では、localhost:8000 にアクセスしアプリの画面が開かれるか確認しましょう
こんな画面が表示されれば、成功しています。
※ターミナル上で Ctrl + C
でサーバを止められます
2. ログイン画面の作成
以下のコマンドを順番に実行していきます。
composer require laravel/jetstream
php artisan jetstream:install livewire
npm install && npm run dev
全部終わるまで5分位かかると思います。もし最後のコマンドでエラーが出たら、node.jsが正しくインストールされていない可能性がありますのでnpm
コマンドが実行できるようにしてください。
3.DBの設定
プロジェクトフォルダ内の.env
ファイルを修正してDB設定をします。
デフォルトでmysqlが設定されているこの6行を1行にします。
ここを↓
こう↓
そして「database」フォルダの下にdatabase.sqlite
という新規ファイルを作成します。
クライアント/サーバー型のDBに対して、SQLiteはこのようにファイルを作成するだけでOKなので楽ですね。
補足 Laravel のDBに対するアプローチ
DBの設定ができたら、DBのアプリの中でテーブルのカラムや型を定義して、主キーを決めて…というのがよくある手順ですが、Laravelでは通常そういうことはしません。
マイグレーションという機能を使い、PHPで書かれたマイグレーションファイルを用意して、テーブルの作成や修正、削除を行います。
従来のやり方がデータファーストというのに対して、この手法はコードファーストと呼ばれ、プロジェクトの途中でのテーブル構造の修正が比較的容易であることから、最近の開発の主流になりつつあります。多分。
「database」フォルダの中に「migrations」というフォルダがあります。この中に入っているのがマイグレーションファイルです。
一番上にある2014_10_12_000000_create_users_table.php
というファイルを見てみましょう。
細かい意味についてここで理解する必要はありませんが、テーブル名やカラム名や型といったテーブル構造をここで定義しているのがなんとな~くわかると思います。
これらのマイグレーションファイルは、まだ実際にDBの中にテーブルとして入ってはいません。
DBはまだ空の状態です。
以下のコマンドを実行することで、テーブルが作成されます。
php artisan migrate
4. ログイン画面の確認
さて、ここでphp artisan serve
を実行して、Webアプリの状態を確認したいと思います。
すると画面右上に、先ほどまではなかった、「Login」「Register」というリンクが存在しているのがわかります。
入力チェックや、パスワード忘れの際のメールによるパスワード再設定、パスワード確認フィールド、複雑さの要件を満たしたパスワードのチェックといったログイン画面と登録画面に最低必要であろう機能が、既にそろった状態で追加されています。
適当なアカウントを作成して、登録をすると、ログインすることができます。
「Profile」では、名前やパスワードの変更、さらには2要素認証の設定やログイン履歴の確認といったこともできるのが確認できます。
sqliteをインストールした人は、以下のコマンドを実行し、今登録したアカウントを確認してみましょう。
cd database
カレントディレクトリの変更
sqlite3 database.sqlite
sqlite の実行
select * from users;
usersテーブルの情報を取得
するとこんな画面が表示されると思います。左からID, 名前, メール, パスワード…となっていますが、注目すべきは、既にパスワードが暗号化された状態になっているということです。
特に意識をしなくてもセキュリティの面でもしっかりしたユーザーテーブルが作成されているのがわかります。
※Ctrl + C
で抜けられます
5. 社員テーブルの作成
では、社員情報を設定したマイグレーションファイルを作ってみましょう。
次のコマンドを実行してください。
※ カレントディレクトリが「database」のままの人は、cd ..
でプロジェクトフォルダにカレントディレクトリを移動してください。
php artisan make:migration create_employees_table --create=employees
エラーがおきなければ「migrations」フォルダ内に新しくファイルが作成されているので、up メソッドの中に2行追加します。
Schema::create('employees', function (Blueprint $table) {
$table->id();
$table->string('name'); //<--新規追加(名前)
$table->string('skill'); //<--新規追加(保有スキル)
$table->timestamps();
});
保存し、php artisan migrate
でテーブルを作成します。
ここから、プロジェクトの全体構成の「MVCパターン」の図に沿って、ルーティング、モデル、コントローラー、ビューを作成していきます。
6. ルーティングの設定
「routes」フォルダの下にweb.php
というファイルがあるので、これを修正します。
一般的なWebサイトでは、Webサーバーの公開フォルダの中にファイルを用意しておくと、そのままそのファイルにアクセスができます。
しかし、Laravelのようなフレームワークを使っている場合、そうはなりません。Laravelは、特定のアドレスにアクセスをすると、そのアドレスに割り付けられたプログラムが実行され、それによって必要な処理や画面表示などが作られます。
そういった機能のことをルーティングと言います。
ファイル内の以下の個所を書き換えます。
書き換え前
Route::middleware(['auth:sanctum', 'verified'])->get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
書き換え後
Route::middleware(['auth:sanctum', 'verified'])->group(function(){
Route::get('/dashboard',[EmployeeController::class, 'index'])->name('dashboard');
Route::get('/employee',[EmployeeController::class, 'add']);
Route::post('/employee',[EmployeeController::class, 'create']);
Route::get('/employee/{employee}', [EmployeeController::class, 'edit']);
Route::post('/employee/{employee}', [EmployeeController::class, 'update']);
});
細かいLaravelの文法については説明しませんが、あるアドレスにアクセスされたら、指定のコントローラーのメソッドを呼び出す、ということを各行で行っています。middlewareがどうこうというところは、ログイン認証済みかどうかを判断しています。
Route::HTTPアクセスの種類(アドレス, 呼び出すメソッド);
また、以下のインポート文も追加するのを忘れないようにしてください。
use App\Http\Controllers\EmployeeController;
7. モデルの作成
次にモデルを作成します。
php artisan make:model Employee
以上です。今回は、モデルの修正は行いません。
8. コントローラーの作成
php artisan make:controller EmployeeController
以上です。
-
コントローラーの修正
ルーティングで設定した5つの遷移先メソッドに、処理を書き込んでいます。
EmployeeController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Employee; use Illuminate\Support\Facades\Log; class EmployeeController extends Controller { public function index(){ $employees = Employee::all(); return view('dashboard', compact('employees')); } public function add(){ return view('add'); } public function create(Request $request){ $this->validate($request, [ 'name' => 'required|min:2', 'skill' => 'required' ]); $employee = new Employee(); $employee->name = $request->name; $employee->skill = $request->skill; $employee->save(); Log::info('added user '.$employee->name.' by '.auth()->user()->name); return redirect('dashboard'); } public function edit(Employee $employee){ return view('edit', compact('employee')); } public function update(Request $request, Employee $employee){ if(isset($_POST['delete'])){ $employee->delete(); Log::info('deleted '.$employee->name.' by '.auth()->user()->name); return redirect('dashboard'); } $employee->name = $request->name; $employee->skill = $request->skill; $employee->save(); Log::info('updated '.$employee->name.' by '.auth()->user()->name); return redirect('dashboard'); } }
入力チェックのための
validate
関数、ログ出力のためのLog::info('メッセージ')
というメソッド(正確にはファサード)を使用しています。
9. ビューの修正・作成
Webサイトでは、画面の表示にHTML形式のファイルを作成し、それをブラウザに表示させます。PHPでWebアプリを作成した場合、HTMLファイル内にPHPのスクリプトを混在させることができますが、著しく可読性を下げます。
少し値を表示させたいだけなのに、HTMLの中にと書かなければならず、HTMLのタグ構造を崩してしまいます。
それを解決するのがLaravelに備わっている**Blade(ブレード)**というテンプレートエンジンです。テンプレートエンジンという言葉を聞くとわけわかりませんが、簡単に言うと、HTMLの中に違和感なくPHPの処理を紛れ込ませる書き方ができる仕組みのことです。
その書き方に従って、今回は以下の3ファイルの修正・追加を行います。
-
dashboard.blade.php
の修正dashboard.blade.php<x-app-layout> <x-slot name="header"> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> {{ __('Dashboard') }} </h2> </x-slot> <table> <thead> <tr> <td>名前</td> <td>スキル</td> <td>操作</td> </tr> </thead> <tbody> @foreach ($employees as $employee) <tr> <td>{{$employee->name}}</td> <td>{{$employee->skill}}</td> <td> <a href="employee/{{$employee->id}}">編集</a> <form method="POST" action="employee/{{$employee->id}}"> <button name="delete">削除</button> {{ csrf_field() }} </form> </td> </tr> @endforeach </tbody> </table> <br> <a href="/employee"> 社員を追加する </a> </x-app-layout>
-
add.blade.php
の追加add.blade.php<x-app-layout> <x-slot name="header"> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> {{ __('Add Employee') }} </h2> </x-slot> <form method="POST" action="/employee"> <label for="name">名前</label> <input type="text" name="name"> <span class="text-danger">{{ $errors->first('name') }}</span> <br> <label for="skill">スキル</label> <textarea name="skill"></textarea> <span class="text-danger">{{ $errors->first('skill') }}</span> <br> <button>登録</button> {{csrf_field()}} </form> </x-app-layout>
-
edit.blade.php
の追加edit.blade.php<x-app-layout> <x-slot name="header"> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> {{ __('Edit Employee') }} </h2> </x-slot> <form method="POST" action="/employee/{{$employee->id}}"> <label for="name">名前</label> <input type="text" name="name" value="{{$employee->name}}"> <br> <label for="skill">スキル</label> <textarea name="skill">{{$employee->skill}}</textarea> <br> <button>更新</button> {{csrf_field()}} </form> </x-app-layout>
登録画面と編集画面はほぼ同じです。違いはフォームの送信先と、選択した従業員の情報がフォーム内に埋め込まれているかどうかです。
どの画面も、フォーム内に {{csrf_filed()}}
という関数が書かれているのにも注目です。これはCSRF対策のためにワンタイムトークンを発行するためのものです。
※csrfとは攻撃手法の一つで、外部からフォームを送信します。大量のフォームを送信したり、悪意のある偽装リクエストを第三者に送らせたりします。
作成されたアプリ
見た目はかなーりしょーもないですが、いくつかのコマンド操作と、たったの6つのファイルに手を加えただけで、社員管理システムを作ることができました。
最後におまけ
- サクッと機能を実装した後はCSSフレームワークやUIライブラリで見た目を整えることに時間を使いましょう。有名どころでいうと、とりあえずみんな使ってるbootstrap、追い風の吹いている感じのtailwind、個人的におすすめなmaterialize, Vuetifyがあります。
- VisualStudioCodeであればXDebugでのデバッグ実行が便利です。
- こんな機能あったらいいのにな~、こんな実装がしたいな~と思ったら大体調べれば方法が出てきます。この記事に落胆してもLaravelの事は嫌いにならないで。
- Webアプリのエンジニアとして頑張っていきたい人は、Laravelと並行してJavaScriptのフレームワークについても触っておいた方が良いです。両者は競合するものではなく、組み合わせて可能性を引き出すことができます。