6
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ゼロからLaravel(社員管理システムを45分で) 2021年版

Last updated at Posted at 2021-02-04

これから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パターン

Untitled.png

2.画面設計

IMG_0950.jpg
絵をかくのは好きな方です

3.実装機能

CRUD操作
登録、一覧表示、更新、削除
ログイン機能
・ログイン画面 ・ログイン後の認証 ・ユーザー登録
セキュリティ対策
「なんでセキュリティ対策しなきゃいけないの?」と思わないで! ・パスワードは暗号化(平文ダメ!) ・CSRF対策 ※csrfとは攻撃手法の一つで、外部からフォームを送信します。大量のフォームを送信したり、悪意のある偽装リクエストを第三者に送らせたりします
入力チェック
・必須項目 ・文字数制限
ログ出力機能
・エラーログ ・いつ、だれがどのユーザーを更新したか

プロジェクトを作成

  1. 適当なフォルダを作成してクリック
    Untitled 1.png

  2. フォルダのパスが書かれているところに cmd と入力して Enter
    Untitled 2.png

  3. コマンドプロンプトが開くので、以下のコマンドを実行
    Untitled 3.png

プロジェクトフォルダが作成され、何やらいろいろダウンロードされます(5分位かかるかも)
Untitled 4.png

  1. 作成されたプロジェクトフォルダを右クリックするなどして、Visual Studio Codeで開きます
    Untitled 5.png

  2. Visual Studio Codeの画面が開くので、Ctrl + @ でターミナルを開きます
    Untitled 6.png

これで準備は完了です
以降はここのターミナルからコマンドを実行しながら開発をしていきます
Untitled 7.png

プログラムの作成

1. アプリケーションを実行する

プロジェクトはアプリケーションに必要なファイル類を一式そろえています。Laravelに内蔵されたWebサーバー機能を使うことで、アプリケーションを実行することが出来ます。

php artisan serve と実行してこんな表示が出れば成功です。ローカルサーバーが立ち上がっています。
Untitled 8.png

※補足ですが、Laravelでは php artisan コマンド [引数] というコマンドを実行することで、Laravel独自のスクリプトファイルを作成したり、サーバーを実行したりといった便利な操作ができます。

では、localhost:8000 にアクセスしアプリの画面が開かれるか確認しましょう
Untitled 9.png

こんな画面が表示されれば、成功しています。

※ターミナル上で Ctrl + C でサーバを止められます

2. ログイン画面の作成

以下のコマンドを順番に実行していきます。

  1. composer require laravel/jetstream
  2. php artisan jetstream:install livewire
  3. npm install && npm run dev

全部終わるまで5分位かかると思います。もし最後のコマンドでエラーが出たら、node.jsが正しくインストールされていない可能性がありますのでnpmコマンドが実行できるようにしてください。

3.DBの設定

プロジェクトフォルダ内の.envファイルを修正してDB設定をします。
Untitled 10.png

デフォルトでmysqlが設定されているこの6行を1行にします。
ここを↓
Untitled 11.png
こう↓
Untitled 12.png

そして「database」フォルダの下にdatabase.sqliteという新規ファイルを作成します。
Untitled 13.png
Untitled 14.png
クライアント/サーバー型のDBに対して、SQLiteはこのようにファイルを作成するだけでOKなので楽ですね。

補足 Laravel のDBに対するアプローチ

DBの設定ができたら、DBのアプリの中でテーブルのカラムや型を定義して、主キーを決めて…というのがよくある手順ですが、Laravelでは通常そういうことはしません。
マイグレーションという機能を使い、PHPで書かれたマイグレーションファイルを用意して、テーブルの作成や修正、削除を行います。
従来のやり方がデータファーストというのに対して、この手法はコードファーストと呼ばれ、プロジェクトの途中でのテーブル構造の修正が比較的容易であることから、最近の開発の主流になりつつあります。多分。

「database」フォルダの中に「migrations」というフォルダがあります。この中に入っているのがマイグレーションファイルです。
Untitled 15.png

一番上にある2014_10_12_000000_create_users_table.phpというファイルを見てみましょう。
細かい意味についてここで理解する必要はありませんが、テーブル名やカラム名や型といったテーブル構造をここで定義しているのがなんとな~くわかると思います。

Untitled 16.png

これらのマイグレーションファイルは、まだ実際にDBの中にテーブルとして入ってはいません。
DBはまだ空の状態です。
以下のコマンドを実行することで、テーブルが作成されます。

php artisan migrate

エラーが出なければ成功です。
Untitled 17.png

4. ログイン画面の確認

さて、ここでphp artisan serve を実行して、Webアプリの状態を確認したいと思います。
Untitled 18.png

すると画面右上に、先ほどまではなかった、「Login」「Register」というリンクが存在しているのがわかります。

入力チェックや、パスワード忘れの際のメールによるパスワード再設定、パスワード確認フィールド、複雑さの要件を満たしたパスワードのチェックといったログイン画面と登録画面に最低必要であろう機能が、既にそろった状態で追加されています。
Untitled 19.png

適当なアカウントを作成して、登録をすると、ログインすることができます。
Untitled 20.png

「Profile」では、名前やパスワードの変更、さらには2要素認証の設定やログイン履歴の確認といったこともできるのが確認できます。
Untitled 21.png

sqliteをインストールした人は、以下のコマンドを実行し、今登録したアカウントを確認してみましょう。

cd database カレントディレクトリの変更
sqlite3 database.sqlite sqlite の実行
select * from users; usersテーブルの情報を取得
Untitled 22.png

するとこんな画面が表示されると思います。左からID, 名前, メール, パスワード…となっていますが、注目すべきは、既にパスワードが暗号化された状態になっているということです。
特に意識をしなくてもセキュリティの面でもしっかりしたユーザーテーブルが作成されているのがわかります。
Ctrl + Cで抜けられます

5. 社員テーブルの作成

では、社員情報を設定したマイグレーションファイルを作ってみましょう。
次のコマンドを実行してください。
※ カレントディレクトリが「database」のままの人は、cd .. でプロジェクトフォルダにカレントディレクトリを移動してください。

php artisan make:migration create_employees_table --create=employees

エラーがおきなければ「migrations」フォルダ内に新しくファイルが作成されているので、up メソッドの中に2行追加します。

yyyy_MM_dd_hhmmss_create_employees_table.php
Schema::create('employees', function (Blueprint $table) {
            $table->id();
            $table->string('name'); //<--新規追加(名前)
            $table->string('skill'); //<--新規追加(保有スキル)
            $table->timestamps();
        });

保存し、php artisan migrate でテーブルを作成します。

ここから、プロジェクトの全体構成の「MVCパターン」の図に沿って、ルーティング、モデル、コントローラー、ビューを作成していきます。

6. ルーティングの設定

「routes」フォルダの下にweb.php というファイルがあるので、これを修正します。
Untitled 23.png

一般的なWebサイトでは、Webサーバーの公開フォルダの中にファイルを用意しておくと、そのままそのファイルにアクセスができます。
しかし、Laravelのようなフレームワークを使っている場合、そうはなりません。Laravelは、特定のアドレスにアクセスをすると、そのアドレスに割り付けられたプログラムが実行され、それによって必要な処理や画面表示などが作られます。
そういった機能のことをルーティングと言います。

ファイル内の以下の個所を書き換えます。

書き換え前

web.php
Route::middleware(['auth:sanctum', 'verified'])->get('/dashboard', function () {
    return view('dashboard');
})->name('dashboard');

書き換え後

web.php
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アクセスの種類(アドレス, 呼び出すメソッド);

また、以下のインポート文も追加するのを忘れないようにしてください。

web.php
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とは攻撃手法の一つで、外部からフォームを送信します。大量のフォームを送信したり、悪意のある偽装リクエストを第三者に送らせたりします。

作成されたアプリ

一覧画面
Untitled 24.png

登録画面
Untitled 25.png

編集画面
Untitled 26.png

見た目はかなーりしょーもないですが、いくつかのコマンド操作と、たったの6つのファイルに手を加えただけで、社員管理システムを作ることができました。

最後におまけ

  • サクッと機能を実装した後はCSSフレームワークやUIライブラリで見た目を整えることに時間を使いましょう。有名どころでいうと、とりあえずみんな使ってるbootstrap、追い風の吹いている感じのtailwind、個人的におすすめなmaterialize, Vuetifyがあります。
  • VisualStudioCodeであればXDebugでのデバッグ実行が便利です。
  • こんな機能あったらいいのにな~、こんな実装がしたいな~と思ったら大体調べれば方法が出てきます。この記事に落胆してもLaravelの事は嫌いにならないで。
  • Webアプリのエンジニアとして頑張っていきたい人は、Laravelと並行してJavaScriptのフレームワークについても触っておいた方が良いです。両者は競合するものではなく、組み合わせて可能性を引き出すことができます。
6
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?