はじめに
Laravel 13でWebアプリケーションを開発する場合、データベースとしてMySQLを使用したいケースは多いと思います。
Laravel 13では新規プロジェクト作成時にSQLiteが標準で設定されていますが、.envを変更することでMySQLへ簡単に切り替えることができます。
今回は、
- Windows 11
- WSL2
- Ubuntu
- Laravel 13
- MySQL
という環境でMySQLをインストールし、Laravel 13から接続します。
さらに、接続確認だけではなく、商品データを例にして、
登録(Create)・一覧表示(Read)・更新(Update)・削除(Delete)
までのCRUD処理を作成します。
Laravel 13でMySQLを使ったWebアプリケーションを開発したい方は参考にしてください。
今回作成するもの
今回は簡単な商品管理機能を作成します。
商品には以下の3項目を持たせます。
- 商品名
- 価格
- 在庫数
最終的に次の操作ができるようにします。
- 商品一覧を表示する
- 商品を新規登録する
- 商品を編集する
- 商品を削除する
LaravelのModel、Migration、Controller、Blade、Routeを使用して実装します。
開発環境
今回の環境は以下を想定しています。
OS:Windows 11
Linux:WSL2 / Ubuntu
Framework:Laravel 13
Database:MySQL
PHP:Laravel 13が動作するPHP環境
すでにLaravel 13のプロジェクトが作成されている前提で進めます。
プロジェクト名は例として、
laravel-mysql-app
とします。
WSL2上でLaravel 13をまだインストールしていない場合は、先にLaravelの開発環境を構築してください。
1. WSL2にMySQLをインストールする
まずWSL2のUbuntuを起動します。
パッケージ情報を更新します。
sudo apt update
続いてMySQL Serverをインストールします。
sudo apt install mysql-server
途中で確認された場合は、
Y
を入力します。
インストールが完了したらMySQLのバージョンを確認します。
mysql --version
バージョン情報が表示されればMySQLのインストールは完了です。
2. MySQLが起動しているか確認する
次のコマンドを実行します。
sudo systemctl status mysql
正常に起動していれば、
active (running)
のように表示されます。
停止している場合は、次のコマンドで起動します。
sudo systemctl start mysql
再度、
sudo systemctl status mysql
を実行して確認します。
WSL2の環境によってはsystemdの設定が必要になる場合があります。
3. MySQLへログインする
UbuntuからMySQLへログインします。
sudo mysql
次のような表示になればログイン成功です。
mysql>
現在作成されているデータベースを確認してみます。
SHOW DATABASES;
4. Laravel用のデータベースを作成する
今回はLaravel用として、
laravel_crud
というデータベースを作成します。
MySQL上で次を実行します。
CREATE DATABASE laravel_crud
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
作成されたことを確認します。
SHOW DATABASES;
一覧に、
laravel_crud
が表示されれば成功です。
5. Laravel用MySQLユーザーを作成する
開発環境であっても、LaravelからMySQLへ接続するためのユーザーを作成しておくと管理しやすくなります。
今回は、
ユーザー名:laravel_user
パスワード:任意の強いパスワード
として作成します。
例えば次のように実行します。
CREATE USER 'laravel_user'@'localhost'
IDENTIFIED BY 'your_secure_password';
作成したユーザーへlaravel_crudデータベースの権限を付与します。
GRANT ALL PRIVILEGES
ON laravel_crud.*
TO 'laravel_user'@'localhost';
権限を反映します。
FLUSH PRIVILEGES;
MySQLから退出します。
EXIT;
6. Laravel 13の.envをMySQL用に変更する
Laravelプロジェクトへ移動します。
cd ~/laravel-mysql-app
Laravel 13の新規プロジェクトではSQLiteが設定されている場合があります。
.envを開き、データベース設定をMySQL用に変更します。
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_crud
DB_USERNAME=laravel_user
DB_PASSWORD=your_secure_password
ここで重要なのが、
DB_CONNECTION=mysql
です。
これによってLaravelがMySQLを使用するようになります。
7. Laravelの設定キャッシュをクリアする
.envを変更したあと、設定キャッシュが残っている場合があります。
念のため次のコマンドを実行します。
php artisan config:clear
続いて、
php artisan cache:clear
も実行しておきます。
8. LaravelからMySQLへ接続できるか確認する
LaravelからMySQLへ正常に接続できるか確認します。
php artisan migrate
正常であればLaravel標準のMigrationが実行されます。
例えば、
INFO Running migrations.
などと表示されます。
MySQL側から確認したい場合は、
mysql -u laravel_user -p
でログインします。
パスワードを入力後、
USE laravel_crud;
続いて、
SHOW TABLES;
を実行します。
Laravelによって作成されたテーブルが表示されれば、
Laravel 13 → MySQL
の接続は成功しています。
Laravel 13でCRUDを作成する
ここから実際にCRUDを作成します。
今回は、
products
テーブルを作成します。
9. ProductモデルとMigrationを作成する
次のArtisanコマンドを実行します。
php artisan make:model Product -m
これによって、
app/Models/Product.php
と、
database/migrations/
以下にMigrationファイルが作成されます。
10. productsテーブルを作成する
作成されたMigrationファイルを開きます。
ファイル名は実行日時によって異なります。
database/migrations/xxxx_xx_xx_xxxxxx_create_products_table.php
up()を次のようにします。
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->unsignedInteger('price');
$table->unsignedInteger('stock')->default(0);
$table->timestamps();
});
今回作成する項目は、
id
name
price
stock
created_at
updated_at
です。
Migrationを実行します。
php artisan migrate
正常に実行されればproductsテーブルが作成されます。
11. Productモデルを設定する
app/Models/Product.phpを開きます。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = [
'name',
'price',
'stock',
];
}
$fillableには、一括代入を許可するカラムを指定しています。
今回は、
name
price
stock
を登録・更新できるようにします。
12. ProductControllerを作成する
CRUD処理を行うControllerを作成します。
php artisan make:controller ProductController --resource
これによって、
app/Http/Controllers/ProductController.php
が作成されます。
--resourceを付けることでCRUDで使用する基本的なメソッドが生成されます。
13. 商品一覧を取得する
ProductController.phpを編集します。
まずProductモデルを読み込みます。
use App\Models\Product;
use Illuminate\Http\Request;
index()を次のようにします。
public function index()
{
$products = Product::orderBy('id', 'desc')->get();
return view('products.index', compact('products'));
}
これでproductsテーブルの商品を取得できます。
14. 商品登録画面を作成する
create()を次のようにします。
public function create()
{
return view('products.create');
}
続いてstore()を作成します。
public function store(Request $request)
{
$validated = $request->validate([
'name' => ['required', 'string', 'max:255'],
'price' => ['required', 'integer', 'min:0'],
'stock' => ['required', 'integer', 'min:0'],
]);
Product::create($validated);
return redirect()
->route('products.index')
->with('success', '商品を登録しました。');
}
ここではバリデーションも設定しています。
商品名は必須、価格と在庫数は0以上の整数としています。
15. 商品編集処理を作成する
edit()を作成します。
public function edit(Product $product)
{
return view('products.edit', compact('product'));
}
Laravelのルートモデルバインディングを利用して、URLのIDに対応するProductを取得します。
続いてupdate()です。
public function update(Request $request, Product $product)
{
$validated = $request->validate([
'name' => ['required', 'string', 'max:255'],
'price' => ['required', 'integer', 'min:0'],
'stock' => ['required', 'integer', 'min:0'],
]);
$product->update($validated);
return redirect()
->route('products.index')
->with('success', '商品を更新しました。');
}
16. 商品削除処理を作成する
destroy()を作成します。
public function destroy(Product $product)
{
$product->delete();
return redirect()
->route('products.index')
->with('success', '商品を削除しました。');
}
これで削除処理も完成です。
ProductController全体
最終的なProductController.phpは次のようになります。
<?php
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Http\Request;
class ProductController extends Controller
{
public function index()
{
$products = Product::orderBy('id', 'desc')->get();
return view('products.index', compact('products'));
}
public function create()
{
return view('products.create');
}
public function store(Request $request)
{
$validated = $request->validate([
'name' => ['required', 'string', 'max:255'],
'price' => ['required', 'integer', 'min:0'],
'stock' => ['required', 'integer', 'min:0'],
]);
Product::create($validated);
return redirect()
->route('products.index')
->with('success', '商品を登録しました。');
}
public function edit(Product $product)
{
return view('products.edit', compact('product'));
}
public function update(Request $request, Product $product)
{
$validated = $request->validate([
'name' => ['required', 'string', 'max:255'],
'price' => ['required', 'integer', 'min:0'],
'stock' => ['required', 'integer', 'min:0'],
]);
$product->update($validated);
return redirect()
->route('products.index')
->with('success', '商品を更新しました。');
}
public function destroy(Product $product)
{
$product->delete();
return redirect()
->route('products.index')
->with('success', '商品を削除しました。');
}
}
17. Routeを設定する
routes/web.phpを開きます。
<?php
use App\Http\Controllers\ProductController;
use Illuminate\Support\Facades\Route;
Route::resource('products', ProductController::class);
Route::resource()を使用することでCRUD用のRouteをまとめて登録できます。
登録されたRouteは次のコマンドで確認できます。
php artisan route:list
productsに関連するRouteが表示されれば正常です。
18. Bladeファイルを作成する
次のディレクトリを作成します。
resources/views/products
その中に、
index.blade.php
create.blade.php
edit.blade.php
を作成します。
19. 商品一覧画面を作成する
resources/views/products/index.blade.phpを作成します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>商品一覧</title>
</head>
<body>
<h1>商品一覧</h1>
@if (session('success'))
<p>{{ session('success') }}</p>
@endif
<p>
<a href="{{ route('products.create') }}">
商品を登録する
</a>
</p>
<table border="1" cellpadding="10">
<thead>
<tr>
<th>ID</th>
<th>商品名</th>
<th>価格</th>
<th>在庫数</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@forelse ($products as $product)
<tr>
<td>{{ $product->id }}</td>
<td>{{ $product->name }}</td>
<td>
{{ number_format($product->price) }}円
</td>
<td>
{{ $product->stock }}
</td>
<td>
<a href="{{ route('products.edit', $product) }}">
編集
</a>
<form
action="{{ route('products.destroy', $product) }}"
method="POST"
style="display:inline;"
>
@csrf
@method('DELETE')
<button
type="submit"
onclick="return confirm('削除しますか?')"
>
削除
</button>
</form>
</td>
</tr>
@empty
<tr>
<td colspan="5">
商品が登録されていません。
</td>
</tr>
@endforelse
</tbody>
</table>
</body>
</html>
20. 商品登録画面を作成する
resources/views/products/create.blade.phpを作成します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>商品登録</title>
</head>
<body>
<h1>商品登録</h1>
@if ($errors->any())
<ul>
@foreach ($errors->all() as $error)
<li>
{{ $error }}
</li>
@endforeach
</ul>
@endif
<form
action="{{ route('products.store') }}"
method="POST"
>
@csrf
<div>
<label>商品名</label>
<input
type="text"
name="name"
value="{{ old('name') }}"
>
</div>
<div>
<label>価格</label>
<input
type="number"
name="price"
value="{{ old('price') }}"
min="0"
>
</div>
<div>
<label>在庫数</label>
<input
type="number"
name="stock"
value="{{ old('stock', 0) }}"
min="0"
>
</div>
<button type="submit">
登録
</button>
</form>
<p>
<a href="{{ route('products.index') }}">
商品一覧へ戻る
</a>
</p>
</body>
</html>
21. 商品編集画面を作成する
resources/views/products/edit.blade.phpを作成します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>商品編集</title>
</head>
<body>
<h1>商品編集</h1>
@if ($errors->any())
<ul>
@foreach ($errors->all() as $error)
<li>
{{ $error }}
</li>
@endforeach
</ul>
@endif
<form
action="{{ route('products.update', $product) }}"
method="POST"
>
@csrf
@method('PUT')
<div>
<label>商品名</label>
<input
type="text"
name="name"
value="{{ old('name', $product->name) }}"
>
</div>
<div>
<label>価格</label>
<input
type="number"
name="price"
value="{{ old('price', $product->price) }}"
min="0"
>
</div>
<div>
<label>在庫数</label>
<input
type="number"
name="stock"
value="{{ old('stock', $product->stock) }}"
min="0"
>
</div>
<button type="submit">
更新
</button>
</form>
<p>
<a href="{{ route('products.index') }}">
商品一覧へ戻る
</a>
</p>
</body>
</html>
22. Laravelを起動する
Laravelの開発サーバーを起動します。
php artisan serve
ブラウザから、
http://127.0.0.1:8000/products
へアクセスします。
商品一覧画面が表示されれば成功です。
「商品を登録する」をクリックして、
商品名:ノートパソコン
価格:120000
在庫数:5
などを登録してみます。
商品一覧に表示されればMySQLへの保存も正常に行われています。
23. MySQLに本当に登録されているか確認する
MySQLへ直接ログインして確認することもできます。
mysql -u laravel_user -p
ログイン後、
USE laravel_crud;
続いて、
SELECT * FROM products;
を実行します。
Laravelから登録した商品が表示されれば正常です。
LaravelからMySQLへ接続できない場合
Laravel 13からMySQLへ接続する際、いくつかのエラーが発生する場合があります。
代表的なものを紹介します。
SQLSTATE[HY000] [2002] Connection refused
例えば、
SQLSTATE[HY000] [2002] Connection refused
が発生した場合、まずMySQLが起動しているか確認します。
sudo systemctl status mysql
停止している場合は、
sudo systemctl start mysql
で起動します。
.envの設定も確認します。
DB_HOST=127.0.0.1
DB_PORT=3306
Access denied for userが発生する場合
例えば、
Access denied for user 'laravel_user'@'localhost'
が表示された場合は、
- ユーザー名
- パスワード
- MySQLユーザーの権限
を確認します。
Laravelの.envとMySQLで作成したユーザー情報が一致している必要があります。
設定変更後は、
php artisan config:clear
を実行してください。
Unknown databaseが発生する場合
例えば、
Unknown database 'laravel_crud'
と表示された場合、指定したデータベースが存在していない可能性があります。
MySQLへログインして、
SHOW DATABASES;
を実行します。
存在しなければ、
CREATE DATABASE laravel_crud
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
で作成します。
could not find driverが発生する場合
環境によっては、
could not find driver
と表示されることがあります。
この場合はPHPのMySQL拡張が利用できるか確認します。
php -m | grep -i mysql
例えば、
mysqli
pdo_mysql
などが表示されるか確認してください。
pdo_mysqlが存在しない場合は、使用しているPHPバージョンに対応したMySQL拡張をインストールする必要があります。
migrateをやり直したい場合
開発中にMigrationをすべて削除して作り直したい場合は、
php artisan migrate:fresh
を使用できます。
ただし、このコマンドは既存テーブルを削除して作り直すため、
登録済みデータも削除されます。
本番環境では不用意に実行しないよう注意してください。
Laravel 13 + MySQLでCRUDを作る基本的な流れ
今回行った処理をまとめると次のようになります。
WSL2
↓
Ubuntu
↓
MySQLインストール
↓
データベース作成
↓
MySQLユーザー作成
↓
Laravel .env設定
↓
php artisan migrate
↓
Model作成
↓
Migration作成
↓
Controller作成
↓
Route設定
↓
Blade作成
↓
CRUD完成
LaravelではModelとEloquent ORMを使用することで、SQLを直接記述しなくてもデータベースを操作できます。
例えば一覧取得は、
Product::all();
登録は、
Product::create($validated);
更新は、
$product->update($validated);
削除は、
$product->delete();
のように記述できます。
Laravelを使う大きなメリットの一つです。
実際の業務システムではここから機能を追加する
今回作った商品CRUDは非常にシンプルですが、基本的な構造は在庫管理システムや顧客管理システムなどでも同じです。
例えば商品管理であれば、ここから、
- 商品コード
- 商品カテゴリー
- 仕入価格
- 販売価格
- 入庫数
- 出庫数
- 現在庫
- 発注点
- 仕入先
などを追加できます。
さらに、
商品マスタ
↓
入庫データ
↓
出庫データ
↓
在庫数計算
と発展させれば、Laravelを利用した在庫管理システムを構築できます。
Excelで管理していた在庫表をLaravelとMySQLによるWebシステムへ移行する場合にも、今回紹介したCRUDが基本となります。
まとめ
今回は、Laravel 13でMySQLを使用する方法について、WSL2へのMySQLインストールからCRUD作成まで紹介しました。
基本的な手順は、
1. WSL2へMySQLをインストール
2. Laravel用データベースを作成
3. Laravel用MySQLユーザーを作成
4. .envをMySQL用に変更
5. php artisan migrateを実行
6. ModelとMigrationを作成
7. Controllerを作成
8. Routeを設定
9. Bladeを作成
10. CRUDを実装
となります。
LaravelとMySQLを接続できるようになると、
- 在庫管理システム
- 顧客管理システム
- 見積管理システム
- 予約管理システム
- 案件管理システム
- 営業管理システム
など、さまざまな業務システムへ発展させることができます。
Laravelを学習する場合も、データベース接続だけで終わらせず、今回のようにCRUDを一度作成してみることで、Model・Migration・Controller・Route・Viewの関係を理解しやすくなります。

