概要
PHPのフレームワークLaravelを使用してCRUDを実装してみました。Laravelを使うにはPHPとComposerのインストールが必要です。
今回使用した環境とバージョン
windows10
php v8.0.10
Composer v2.3.10
laravel v9.23.0
ターミナルはPowerShellを使用しています。
プロジェクトファイル作成
Composerを使用してプロジェクトの作成をターミナルで行います。プロジェクト名はcrudとしました。
1 |
composer create-project laravel/laravel crud |
作成したプロジェクトへ移動します。
1 |
cd crud |
データベースの作成と設定
データベースは手軽に利用できるsqliteを使用しました。databaseディレクトリにdatabase.sqliteファイルを作成します。
1 |
New-Item database/database.sqlite |
.envファイルを開きDB_CONNECTIONをsqliteに変更をして、その他のデータベース設定は削除するかコメントアウトします。
1 2 3 4 5 6 |
DB_CONNECTION=sqlite # DB_HOST=127.0.0.1 # DB_PORT=3306 # DB_DATABASE=laravel # DB_USERNAME=root # DB_PASSWORD= |
Migration作成
ターミナルにコマンドを打ちMigrationファイルを作成します。
1 |
php artisan make:migration create_products_table |
database/migrationsディレクトリに[作成日時]_create_products_table.phpが生成されます。ファイルにコードを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('products', function (Blueprint $table) { $table->id(); $table->string('name'); $table->text('detail'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('products'); } }; |
次のコマンドでMigrationを実行します。
1 |
php artisan migrate |
ControllerとModelを作成
次のコマンドでControllerとModelを作成をします。resourceオプションを指定するとCRUDに使うアクションが自動的に用意されます。modelオプションを指定してModelファイルも一緒に作成しています。
1 |
php artisan make:controller ProductController --resource --model=Product |
app/Http/ControllersにProductController.phpが作成されるのでコードを追記します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
<?php namespace App\Http\Controllers; use App\Models\Product; use Illuminate\Http\Request; class ProductController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $products = Product::oldest()->get(); return view('products.index',compact('products')); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { return view('products.create'); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $request->validate([ 'name' => 'required', 'detail' => 'required', ]); Product::create($request->all()); return redirect()->route('products.index') ->with('success','新規作成しました。'); } /** * Display the specified resource. * * @param \App\Models\Product $product * @return \Illuminate\Http\Response */ public function show(Product $product) { return view('products.show',compact('product')); } /** * Show the form for editing the specified resource. * * @param \App\Models\Product $product * @return \Illuminate\Http\Response */ public function edit(Product $product) { return view('products.edit',compact('product')); } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param \App\Models\Product $product * @return \Illuminate\Http\Response */ public function update(Request $request, Product $product) { $request->validate([ 'name' => 'required', 'detail' => 'required', ]); $product->update($request->all()); return redirect()->route('products.index') ->with('success','更新しました。'); } /** * Remove the specified resource from storage. * * @param \App\Models\Product $product * @return \Illuminate\Http\Response */ public function destroy(Product $product) { $product->delete(); return redirect()->route('products.index') ->with('success','削除しました。'); } } |
app/ModelsにProduct.phpが作成されるのでコードを追記します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Product extends Model { use HasFactory; protected $fillable = [ 'name', 'detail' ]; } |
Routeの設定
routes/web.phpを開きルートを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\ProductController; /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::resource('products', ProductController::class); |
Bladeファイル作成
Resources/Viewsの中にproductsディレクトリを作成し、その中にBladeファイルを作成します。
- layout.blade.php
- index.blade.php
- create.blade.php
- edit.blade.php
- show.blade.php
1 2 3 4 5 6 |
mkdir resources/views/products New-Item resources/views/products/layout.blade.php New-Item resources/views/products/index.blade.php New-Item resources/views/products/create.blade.php New-Item resources/views/products/edit.blade.php New-Item resources/views/products/show.blade.php |
resources/views/products/layout.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<!DOCTYPE html> <html lang="ja"> <head> <title>Laravel 9 CRUD</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css"> </head> <body> <div class="container"> @yield('content') </div> </body> </html> |
index.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
@extends('products.layout') @section('content') <h2 class="subtitle has-text-centered mt-4">Laravel 9 CRUD</h2> @if ($message = Session::get('success')) <article class="message is-success"> <div class="message-header"> <p>Success</p> </div> <div class="message-body"> <p>{{ $message }}</p> </div> </article> @endif <div class="column is-8 is-offset-2"> <a class="button is-primary my-4 is-fullwidth" href="{{ route('products.create') }}"> 新規作成</a> <table class="table is-bordered is-striped has-text-centered is-fullwidth"> <tr> <th>ID</th> <th>製品名</th> {{-- <th>Details</th> --}} <th>操作</th> </tr> @foreach ($products as $product) <tr> {{-- <td>{{ ++$i }}</td> --}} <td>{{ $product->id }}</td> <td>{{ $product->name }}</td> {{-- <td>{{ $product->detail }}</td> --}} <td> <form action="{{ route('products.destroy',$product->id) }}" method="POST"> <a class="button is-info" href="{{ route('products.show',$product->id) }}">詳細を表示</a> <a class="button is-success" href="{{ route('products.edit',$product->id) }}">編集</a> @csrf @method('DELETE') <button type="submit" class="button is-danger">削除</button> </form> </td> </tr> @endforeach </table> </div> @endsection |
create.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
@extends('products.layout') @section('content') <h2 class="subtitle has-text-centered mt-4">新規作成</h2> @if ($errors->any()) <article class="message is-danger"> <div class="message-header"> <p>エラー!! 入力内容に問題がありました。</p> </div> <div class="message-body"> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> </article> @endif <div class="column is-8 is-offset-2"> <form action="{{ route('products.store') }}" method="POST"> @csrf <h3 class="has-text-weight-bold">製品名:</h3> <input class="input" type="text" name="name" placeholder="製品名"> <h3 class="has-text-weight-bold">詳細:</h3> <textarea class="textarea is-medium" name="detail" placeholder="詳細"></textarea> <div class="columns"> <div class="column"> <button type="submit" class="button is-success my-4">送信</button> </div> <div class="has-text-right column"> <a class="button is-info my-4" href="{{ route('products.index') }}"> 戻る</a> </div> </div> </form> </div> @endsection |
edit.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
@extends('products.layout') @section('content') <h2 class="subtitle has-text-centered mt-4">編集</h2> @if ($errors->any()) <div class="has-background-danger"> <p> <span class="has-text-weight-bold">エラー!</span> 入力内容に問題がありました。 </p> <ul> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif <form class="column is-8 is-offset-2" action="{{ route('products.update',$product->id) }}" method="POST"> @csrf @method('PUT') <h3 class="has-text-weight-bold">製品名:</h3> <input class="input" type="text" name="name" value="{{ $product->name }}" placeholder="製品名"> <h3 class="has-text-weight-bold">詳細:</h3> <textarea class="input" style="height:150px" name="detail" placeholder="Detail">{{ $product->detail }}</textarea> <div class="columns"> <div class="column"> <button type="submit" class="button is-success my-4">送信</button> </div> <div class="has-text-right column"> <a class="button is-info my-4" href="{{ route('products.index') }}"> 戻る</a> </div> </div> </form> @endsection |
show.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@extends('products.layout') @section('content') <h2 class="subtitle has-text-centered mt-4"> 詳細</h2> <div class="media-content column is-8 is-offset-2"> <h3 class="has-text-weight-bold">製品名:</h3> <div class="box"> <p>{{ $product->name }}</p> </div> <h3 class="has-text-weight-bold">詳細:</h3> <div class="box"> {{ $product->detail }} </div> <div class="has-text-right"> <a class="button is-info my-4 has-right" href="{{ route('products.index') }}"> 戻る</a> </div> </div> @endsection |
アプリを実行する
ターミナルにartisanコマンドを入力して開発サーバーを起動させます。
1 |
php artisan serve |
ブラウザで次のURLにアクセスするとアプリが実行されます。
次回の記事でLAMP環境へデプロイします。
ソースコードはGitHubにあります。
最後までお読みいただきありがとうございました。