目次
Laravelの記事一覧は下記
PHPフレームワークLaravelの使い方
Laravelバージョン
動作確認はLaravel Framework 7.19.1で行っています
前提条件
eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っています
Laravelで入力値エラーチェック(validate)を実装する
Laravelでフラッシュデータ(直後のHTTPリクエストの間だけセッションに保存されるデータ)を使う
本記事は上記の内容を理解している前提で書かれています
LaravelでDIを使う
本記事は上記で作成したフォルダとファイルを使用します
Laravelでデータベースを扱う準備をする
Laravelでテーブル作成
Laravelで初期データ投入
本記事は上記ので作成したデータベースとレコードを使用します
サービスクラス作成
(1) /sample/app/Services/InterfacesフォルダにTable2Service.php作成
<?php
namespace App\Services\Interfaces;
interface Table2Service
{
    public function __construct();
    public function select($id, $varchar_col, $int_col, $datetime_col, $date_col, $time_col);
    public function insert($table1_id, $varchar_col, $int_col, $datetime_col, $date_col, $time_col);
    public function update($id, $table1_id, $varchar_col, $int_col, $datetime_col, $date_col, $time_col);
    public function delete($id);
}
(2) /sample/app/Services/ImplフォルダにTable2ServiceImpl.php作成
<?php
namespace App\Services\Impl;
use App\Services\Interfaces\Table2Service;
use Illuminate\Support\Facades\DB;
class Table2ServiceImpl implements Table2Service
{
    public function __construct()
    {
    }
    public function select($id, $varchar_col, $int_col, $datetime_col, $date_col, $time_col)
    {
        $db = DB::table('table2')
                    ->leftJoin('table1', 'table2.table1_id', '=', 'table1.id')
                    ->leftJoin('table3', 'table2.id', '=', 'table3.table2_id')
                    ->select([
                        'table1.id            as table1_id',
                        'table1.varchar_col   as table1_varchar_col',
                        'table1.int_col       as table1_int_col',
                        'table1.datetime_col  as table1_datetime_col',
                        'table1.date_col      as table1_date_col',
                        'table1.time_col      as table1_time_col',
                        'table2.id            as table2_id',
                        'table2.varchar_col   as table2_varchar_col',
                        'table2.int_col       as table2_int_col',
                        'table2.datetime_col  as table2_datetime_col',
                        'table2.date_col      as table2_date_col',
                        'table2.time_col      as table2_time_col',
                        'table3.id            as table3_id',
                        'table3.varchar_col   as table3_varchar_col',
                        'table3.int_col       as table3_int_col',
                        'table3.datetime_col  as table3_datetime_col',
                        'table3.date_col      as table3_date_col',
                        'table3.time_col      as table3_time_col',
                    ]);
        if (!is_null($id)) {
            $db->where('table2.id', '=', $id);
        }
        if (!is_null($varchar_col)) {
            $db->where('table2.varchar_col', 'like', '%'. addcslashes($varchar_col, '\\_%') . '%');
        }
        if (!is_null($int_col)) {
            $db->where('table2.int_col', '=', $int_col);
        }
        if (!is_null($datetime_col)) {
            $db->where('table2.datetime_col', '=', $datetime_col);
        }
        if (!is_null($date_col)) {
            $db->where('table2.date_col', '=', $date_col);
        }
        if (!is_null($time_col)) {
            $db->where('table2.time_col', '=', $time_col);
        }
        $recordList = $db->get();
        return $recordList;
    }
    public function insert($table1_id, $varchar_col, $int_col, $datetime_col, $date_col, $time_col)
    {
        $id = DB::table('table2')->insertGetId(
            [
                'table1_id' => $table1_id,
                'varchar_col' => $varchar_col,
                'int_col' => $int_col,
                'datetime_col' => $datetime_col,
                'date_col' => $date_col,
                'time_col' => $time_col,
            ]
        );
        return $id;
    }
    public function update($id, $table1_id, $varchar_col, $int_col, $datetime_col, $date_col, $time_col)
    {
        $affected = DB::table('table2')
                       ->where('id', '=', $id)
                       ->update([
                           'table1_id' => $table1_id,
                           'varchar_col' => $varchar_col,
                           'int_col' => $int_col,
                           'datetime_col' => $datetime_col,
                           'date_col' => $date_col,
                           'time_col' => $time_col,
                       ]);
        return $affected;
    }
    public function delete($id)
    {
        $affected = DB::table('table2')
                      ->where('id', '=', $id)
                      ->delete();
        return $affected;
    }
}
これがデータベースにselect、insert、update、deleteしている処理になります
コードを見ればどんなSQLが発行されるかわかると思います。説明も不要でしょう
ここで使用していないメソッドは下記で確認できます
Laravel 7.x データベース:クエリビルダ
また、トランザクションを使用したい場合は下記でできます
Laravel 7.x データベース:利用開始 データベーストランザクション
(3) /sample/tests/Services/ImplフォルダにTable2ServiceImpl.php作成
<?php
namespace Tests\Services\Impl;
use App\Services\Interfaces\Table2Service;
class Table2ServiceImpl implements Table2Service
{
    public function __construct()
    {
    }
    public function select($id, $varchar_col, $int_col, $datetime_col, $date_col, $time_col)
    {
    }
    public function insert($table1_id, $varchar_col, $int_col, $datetime_col, $date_col, $time_col)
    {
    }
    public function update($id, $table1_id, $varchar_col, $int_col, $datetime_col, $date_col, $time_col)
    {
    }
    public function delete($id)
    {
    }
}
DI登録
(1) /sample/app/Providers/DiServiceProvider.phpに下記を追記
use App\Services\Interfaces\Table2Service;
(2) /sample/app/Providers/DiServiceProvider.phpのregisterメソッドに下記を追記
app()->singleton(Table2Service::class, $prefix . 'Table2ServiceImpl');
DiServiceProvider.phpはLaravelでDIを使うで作成したファイルです
LaravelでDIを使うでconfig/app.phpのprovidersに登録してあります
フォームリクエストの作成
/sample/app/Http/Requests/Table2Request.php作成
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class Table2Request extends FormRequest
{
    public function authorize()
    {
        return true;
    }
    public function rules()
    {
        $method = $this->getMethod();
        $idRequire = 'nullable';
        $url = $this->url();
        $urlArray = explode("/", $url);
        $urlTail = array_pop($urlArray);
        if ($method === 'POST' && ($urlTail === 'update-query-builder' || $urlTail === 'delete-query-builder')) {
            $idRequire = 'required';
        }
        return [
            'id'               => [$idRequire, 'numeric', 'max:18446744073709551615'],
            'table1_id'        => ['nullable', 'numeric', 'max:18446744073709551615'],
            'varchar_col'      => ['nullable', 'max:255'],
            'int_col'          => ['nullable', 'integer', 'max:2147483647'],
            'datetime_col'     => ['nullable', 'date_format:Y-m-d H:i:s'],
            'date_col'         => ['nullable', 'date_format:Y-m-d'],
            'time_col'         => ['nullable', 'date_format:H:i:s'],
        ];
    }
}
Controllerにメソッド追加
(1) /sample/app/Http/Controllers/SampleController.phpにuse文を追記
use App\Http\Requests\Table2Request;
use App\Services\Interfaces\Table2Service;
(2) /sample/app/Http/Controllers/SampleController.phpにselectQueryBuilderメソッド、insertQueryBuilderメソッド、updateQueryBuilderメソッド、deleteQueryBuilderメソッドを追記
    public function selectQueryBuilder(Table2Request $request, Table2Service $table2Service)
    {
        if (is_null($request->session()->get('errors'))) {
            $request->flash();
        }
        $id = $request->input('id');
        $varchar_col = $request->input('varchar_col');
        $int_col =  $request->input('int_col');
        $datetime_col =  $request->input('datetime_col');
        $date_col =  $request->input('date_col');
        $time_col =  $request->input('time_col');
        $recordList  = [];
        if ($request->getMethod() === 'POST') {
            $recordList = $table2Service->select($id, $varchar_col, $int_col, $datetime_col, $date_col, $time_col);
        }
        $data = [
            'recordList' => $recordList
        ];
        return view('sample.select', $data);
    }
    public function insertQueryBuilder(Table2Request $request, Table2Service $table2Service)
    {
        if (is_null($request->session()->get('errors'))) {
            $request->flash();
        }
        $table1_id = $request->input('table1_id');
        $varchar_col = $request->input('varchar_col');
        $int_col =  $request->input('int_col');
        $datetime_col =  $request->input('datetime_col');
        $date_col =  $request->input('date_col');
        $time_col =  $request->input('time_col');
        $id  = null;
        if ($request->getMethod() === 'POST') {
            $id = $table2Service->insert($table1_id, $varchar_col, $int_col, $datetime_col, $date_col, $time_col);
        }
        $data = [
            'id' => $id
        ];
        return view('sample.insert', $data);
    }
    public function updateQueryBuilder(Table2Request $request, Table2Service $table2Service)
    {
        if (is_null($request->session()->get('errors'))) {
            $request->flash();
        }
        $id = $request->input('id');
        $table1_id = $request->input('table1_id');
        $varchar_col = $request->input('varchar_col');
        $int_col =  $request->input('int_col');
        $datetime_col =  $request->input('datetime_col');
        $date_col =  $request->input('date_col');
        $time_col =  $request->input('time_col');
        $affected  = null;
        if ($request->getMethod() === 'POST') {
            $affected = $table2Service->update($id, $table1_id, $varchar_col, $int_col, $datetime_col, $date_col, $time_col);
        }
        $data = [
            'affected' => $affected
        ];
        return view('sample.update', $data);
    }
    public function deleteQueryBuilder(Table2Request $request, Table2Service $table2Service)
    {
        if (is_null($request->session()->get('errors'))) {
            $request->flash();
        }
        $id = $request->input('id');
        $affected  = null;
        if ($request->getMethod() === 'POST') {
            $affected = $table2Service->delete($id);
        }
        $data = [
            'affected' => $affected
        ];
        return view('sample.delete', $data);
    }
先ほど作成したフォームリクエストを使って入力値を受け取り、先ほど作成したサービスクラスでデータベースアクセス処理を行っています
この記事では入力画面と完了画面を同じメソッドで処理していますが、これはメソッドを分けているとサンプルコードが長くなり、記事が見にくくなるので1つのメソッドで処理しているだけです
実際の開発ではif ($request->getMethod() === 'POST')というif文など使わずにメソッドを分けましょう
(3) /sample/routes/web.phpに下記を追記
Route::match(['get', 'post'],'sample/select-query-builder', 'SampleController@selectQueryBuilder');
Route::match(['get', 'post'],'sample/insert-query-builder', 'SampleController@insertQueryBuilder');
Route::match(['get', 'post'],'sample/update-query-builder', 'SampleController@updateQueryBuilder');
Route::match(['get', 'post'],'sample/delete-query-builder', 'SampleController@deleteQueryBuilder');
viewの作成
(1) /sample/resources/views/sample/select.blade.phpファイル作成
<html>
    <head>
        <title>sample</title>
        <style>
        .sample-table {
            border-collapse:collapse;
            white-space: nowrap;
            border: 1px solid #000000;
        }
        .sample-table thead {
            background-color: #33CCFF;
            color: #FFFFFF;
            font-weight: bold;
        }
        .sample-table td {
            padding-left:10px;
            padding-right:10px;
            border: 1px solid #000000;
        }
        </style>
    </head>
    <body>
        <form action="{{ url('sample/select-query-builder') }}" method="post">
            @csrf
            @error('id')
                @foreach ($errors->get('id') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>id<input type="text" name="id" value="{{ old('id') }}"></div>
            @error('varchar_col')
                @foreach ($errors->get('varchar_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>varchar_col<input type="text" name="varchar_col" value="{{ old('varchar_col') }}"></div>
            @error('int_col')
                @foreach ($errors->get('int_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>int_col<input type="text" name="int_col" value="{{ old('int_col') }}"></div>
            @error('datetime_col')
                @foreach ($errors->get('datetime_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>datetime_col<input type="text" name="datetime_col" value="{{ old('datetime_col') }}"></div>
            @error('date_col')
                @foreach ($errors->get('date_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>date_col<input type="text" name="date_col" value="{{ old('date_col') }}"></div>
            @error('time_col')
                @foreach ($errors->get('time_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>time_col<input type="text" name="time_col" value="{{ old('time_col') }}"></div>
            <input type="submit" >
        </form>
        <br>
        <table class="sample-table">
            <thead>
                <tr>
                    <td colspan=6>table1</td>
                    <td colspan=6>table2</td>
                    <td colspan=6>table3</td>
                </tr>
                <tr>
                    <td>id</td>
                    <td>varchar_col</td>
                    <td>int_col</td>
                    <td>datetime_col</td>
                    <td>date_col</td>
                    <td>time_col</td>
                    <td>id</td>
                    <td>varchar_col</td>
                    <td>int_col</td>
                    <td>datetime_col</td>
                    <td>date_col</td>
                    <td>time_col</td>
                    <td>id</td>
                    <td>varchar_col</td>
                    <td>int_col</td>
                    <td>datetime_col</td>
                    <td>date_col</td>
                    <td>time_col</td>
                </tr>
            </thead>
            <tbody>
                @foreach ($recordList as $record)
                <tr>
                    <td>{{ $record->table1_id }}</td>
                    <td>{{ $record->table1_varchar_col }}</td>
                    <td>{{ $record->table1_int_col }}</td>
                    <td>{{ $record->table1_datetime_col }}</td>
                    <td>{{ $record->table1_date_col }}</td>
                    <td>{{ $record->table1_time_col }}</td>
                    <td>{{ $record->table2_id }}</td>
                    <td>{{ $record->table2_varchar_col }}</td>
                    <td>{{ $record->table2_int_col }}</td>
                    <td>{{ $record->table2_datetime_col }}</td>
                    <td>{{ $record->table2_date_col }}</td>
                    <td>{{ $record->table2_time_col }}</td>
                    <td>{{ $record->table3_id }}</td>
                    <td>{{ $record->table3_varchar_col }}</td>
                    <td>{{ $record->table3_int_col }}</td>
                    <td>{{ $record->table3_datetime_col }}</td>
                    <td>{{ $record->table3_date_col }}</td>
                    <td>{{ $record->table3_time_col }}</td>
                </tr>
                @endforeach
            </tbody>
        </table>
    </body>
</html>
(2) /sample/resources/views/sample/insert.blade.phpファイル作成
<html>
    <head>
        <title>sample</title>
    </head>
    <body>
        <form action="{{ url('sample/insert-query-builder') }}" method="post">
            @csrf
            @error('table1_id')
                @foreach ($errors->get('table1_id') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>table1_id<input type="text" name="table1_id" value="{{ old('table1_id') }}"></div>
            @error('varchar_col')
                @foreach ($errors->get('varchar_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>varchar_col<input type="text" name="varchar_col" value="{{ old('varchar_col') }}"></div>
            @error('int_col')
                @foreach ($errors->get('int_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>int_col<input type="text" name="int_col" value="{{ old('int_col') }}"></div>
            @error('datetime_col')
                @foreach ($errors->get('datetime_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>datetime_col<input type="text" name="datetime_col" value="{{ old('datetime_col') }}"></div>
            @error('date_col')
                @foreach ($errors->get('date_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>date_col<input type="text" name="date_col" value="{{ old('date_col') }}"></div>
            @error('time_col')
                @foreach ($errors->get('time_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>time_col<input type="text" name="time_col" value="{{ old('time_col') }}"></div>
            <input type="submit" >
        </form>
        <br>
        @isset($id)
            <div>新規id:{{$id}}</div>
        @endif
    </body>
</html>
(3) /sample/resources/views/sample/update.blade.phpファイル作成
<html>
    <head>
        <title>sample</title>
    </head>
    <body>
        <form action="{{ url('sample/update-query-builder') }}" method="post">
            @csrf
            @error('id')
                @foreach ($errors->get('id') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>id<input type="text" name="id" value="{{ old('id') }}"></div>
            @error('table1_id')
                @foreach ($errors->get('table1_id') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>table1_id<input type="text" name="table1_id" value="{{ old('table1_id') }}"></div>
            @error('varchar_col')
                @foreach ($errors->get('varchar_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>varchar_col<input type="text" name="varchar_col" value="{{ old('varchar_col') }}"></div>
            @error('int_col')
                @foreach ($errors->get('int_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>int_col<input type="text" name="int_col" value="{{ old('int_col') }}"></div>
            @error('datetime_col')
                @foreach ($errors->get('datetime_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>datetime_col<input type="text" name="datetime_col" value="{{ old('datetime_col') }}"></div>
            @error('date_col')
                @foreach ($errors->get('date_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>date_col<input type="text" name="date_col" value="{{ old('date_col') }}"></div>
            @error('time_col')
                @foreach ($errors->get('time_col') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>time_col<input type="text" name="time_col" value="{{ old('time_col') }}"></div>
            <input type="submit" >
        </form>
        <br>
        @isset($affected)
            <div>値が変更された行数:{{$affected}}</div>
        @endif
    </body>
</html>
(4) /sample/resources/views/sample/delete.blade.phpファイル作成
<html>
    <head>
        <title>sample</title>
    </head>
    <body>
        <form action="{{ url('sample/delete-query-builder') }}" method="post">
            @csrf
            @error('id')
                @foreach ($errors->get('id') as $error)
                    <div style="color:red;">{{ $error }}</div>
                @endforeach
            @enderror
            <div>id<input type="text" name="id" value="{{ old('id') }}"></div>
            <input type="submit" >
        </form>
        <br>
        @isset($affected)
            <div>削除された行数:{{$affected}}</div>
        @endif
    </body>
</html>
動作確認
(1) http://localhost/laravelSample/sample/insert-query-builder
送信ボタンをクリックするとinsertが実行されます
(2) http://localhost/laravelSample/sample/update-query-builder
送信ボタンをクリックするとレコードが更新されます
(3) http://localhost/laravelSample/sample/delete-query-builder

送信ボタンをクリックするとレコードが削除されます
(4) http://localhost/laravelSample/sample/select-query-builder
送信ボタンをクリックするとレコードがselectされます


