このチュートリアルでは、**XAMPPとComposerを使ってLaravelで簡単なタスク管理アプリ(MiniCRUD)**を作ります。
タスクの追加、一覧表示、更新、削除を体験し、Laravelの基本を最短で学びましょう!🚀
✅ 前提環境
以下の環境を準備してください:
- OS: Windows(XAMPPインストール済み)
- XAMPP: ApacheとMySQL(MariaDB)が起動可能
- Composer: インストール済み
- エディタ: VS Code推奨
確認コマンド(ターミナル/コマンドプロンプトで実行):
php -v # PHPバージョン確認(例: 8.2.12)
composer -V # Composerバージョン確認(例: 2.x.x)
🧭 ゴールの全体像
以下の手順で、MiniCRUDアプリを構築します:
- XAMPPを起動(Apache/MySQL)
- phpMyAdminでデータベース作成(
laravel_app) - ComposerでLaravelプロジェクト作成
-
.envを編集してデータベース接続 - マイグレーションで
tasksテーブル作成 - モデル、コントローラ、ビューを作成
-
php artisan serveでアプリ起動 - CRUD(追加、一覧、更新、削除)を確認
✨ 完成イメージ: ブラウザでタスクを追加/更新/削除でき、シンプルでカッコいいUIで表示!
🛠 手順とコード
1. XAMPP起動
- XAMPP Control Panelを開き、ApacheとMySQLを起動。
- ✅ ポイント: Apache(ポート80)とMySQL(ポート3306)が緑色で起動していることを確認。
2. データベース作成(phpMyAdmin)
- ブラウザで http://localhost/phpmyadmin/ を開く
- 「データベース」→「新規作成」
-
名前:
laravel_app、照合順序:utf8mb4_general_ci
💡 なぜ必要? → タスクやセッションを保存するための領域
🔒 セキュリティ → 本番ではroot以外のユーザーを作成
3. Laravelプロジェクト作成
composer create-project laravel/laravel my-laravel-app
cd my-laravel-app
php artisan --version
👉 ComposerがLaravel(例: 12.26.2)をインストール。
4. .env編集(データベース接続とセッション設定)
ファイル: my-laravel-app/.env
APP_NAME="MiniCRUD"
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_app
DB_USERNAME=root
DB_PASSWORD=
SESSION_DRIVER=file
コマンド:
php artisan key:generate
php artisan config:clear
5. マイグレーション作成(tasksテーブル)
コマンド:
php artisan make:migration create_tasks_table --create=tasks
ファイル: database/migrations/xxxx_xx_xx_xxxxxx_create_tasks_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* マイグレーションを実行してtasksテーブルを作成
*/
public function up(): void
{
Schema::create('tasks', function (Blueprint $table) {
$table->id(); // 主キー(自動増分ID)
$table->string('title'); // タスクのタイトル(必須、最大255文字)
$table->text('body')->nullable(); // タスクの本文(任意、長めのテキスト)
$table->timestamps(); // 作成日時と更新日時を自動記録
});
}
/**
* マイグレーションを元に戻し、tasksテーブルを削除
*/
public function down(): void
{
Schema::dropIfExists('tasks');
}
};
実行:
php artisan migrate
6. モデル作成(Task)
コマンド:
php artisan make:model Task
ファイル: app/Models/Task.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
/**
* マスアサインメントを許可するカラム
* @var array
*/
protected $fillable = ['title', 'body'];
}
7. コントローラ作成(TaskController)
コマンド:
php artisan make:controller TaskController
ファイル: app/Http/Controllers/TaskController.php
<?php
namespace App\Http\Controllers;
use App\Models\Task;
use Illuminate\Http\Request;
class TaskController extends Controller
{
/**
* タスク一覧を表示
* @return \Illuminate\View\View
*/
public function index()
{
$tasks = Task::latest()->get();
return view('tasks.index', compact('tasks'));
}
/**
* 新しいタスクを保存
*/
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|max:100',
'body' => 'nullable|string|max:1000',
]);
Task::create($validated);
return redirect()->route('tasks.index')->with('status', '追加しました!');
}
/**
* 既存のタスクを更新
*/
public function update(Request $request, Task $task)
{
$validated = $request->validate([
'title' => 'required|string|max:100',
'body' => 'nullable|string|max:1000',
]);
$task->update($validated);
return redirect()->route('tasks.index')->with('status', '更新しました!');
}
/**
* タスクを削除
*/
public function destroy(Task $task)
{
$task->delete();
return redirect()->route('tasks.index')->with('status', '削除しました!');
}
}
8. ルート設定
ファイル: routes/web.php
<?php
use App\Http\Controllers\TaskController;
use Illuminate\Support\Facades\Route;
// ルートURL('/')にアクセスしたら、tasks.indexにリダイレクト
Route::get('/', fn() => redirect()->route('tasks.index'));
// タスク一覧を表示(GET /tasks)
Route::get('/tasks', [TaskController::class, 'index'])->name('tasks.index');
// 新しいタスクを保存(POST /tasks)
Route::post('/tasks', [TaskController::class, 'store'])->name('tasks.store');
// タスクを更新(PUT /tasks/{task})
Route::put('/tasks/{task}', [TaskController::class, 'update'])->name('tasks.update');
// タスクを削除(DELETE /tasks/{task})
Route::delete('/tasks/{task}', [TaskController::class, 'destroy'])->name('tasks.destroy');
9. ビュー作成(index.blade.php)
ファイル: resources/views/tasks/index.blade.php
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>MiniCRUD(Laravel)</title>
<style>
body { font-family: 'Segoe UI', sans-serif; background: #f9fafb; margin: 0; padding: 20px; }
.container { max-width: 900px; margin: auto; background: #fff; padding: 20px; border-radius: 12px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); }
h1 { text-align: center; margin-bottom: 20px; color: #333; }
form input, form textarea { width: 100%; padding: 8px; margin: 6px 0; border: 1px solid #ccc; border-radius: 6px; }
button { background: #2563eb; color: #fff; padding: 6px 12px; border: none; border-radius: 6px; cursor: pointer; }
button:hover { background: #1d4ed8; }
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th, td { padding: 10px; border-bottom: 1px solid #eee; text-align: left; }
tr:hover { background: #f1f5f9; }
.status { color: green; font-weight: bold; margin-bottom: 10px; }
.inline { display: inline-block; }
</style>
</head>
<body>
<div class="container">
<h1>📝 MiniCRUD</h1>
<!-- 成功メッセージ -->
@if(session('status'))
<p class="status">{{ session('status') }}</p>
@endif
<!-- 新規追加フォーム -->
<form method="post" action="{{ route('tasks.store') }}">
@csrf
<input name="title" placeholder="タイトル" required>
<textarea name="body" placeholder="メモ"></textarea>
<button>追加</button>
</form>
<h2>一覧</h2>
@if($tasks->isEmpty())
<p>まだありません</p>
@else
<table>
<tr><th>ID</th><th>タイトル</th><th>メモ</th><th>操作</th></tr>
@foreach($tasks as $t)
<tr>
<td>{{ $t->id }}</td>
<td>
<form class="inline" method="post" action="{{ route('tasks.update', $t) }}">
@csrf @method('PUT')
<input name="title" value="{{ $t->title }}">
<textarea name="body">{{ $t->body }}</textarea>
<button>更新</button>
</form>
</td>
<td>{{ $t->body }}</td>
<td>
<form class="inline" method="post" action="{{ route('tasks.destroy', $t) }}">
@csrf @method('DELETE')
<button style="background:#dc2626">削除</button>
</form>
</td>
</tr>
@endforeach
</table>
@endif
</div>
</body>
</html>
10. アプリ起動
php artisan serve
ブラウザで → http://127.0.0.1:8000

🔧 つまずきポイントと対策
-
「Base table already exists」
👉php artisan migrate:fresh(※データ削除される) -
セッションエラー
👉.envでSESSION_DRIVER=fileに変更 orphp artisan session:table -
CSRFエラー(419 Page Expired)
👉 フォームに@csrfを追加、php artisan key:generate -
ページが真っ白
👉.envでAPP_DEBUG=true、ログ確認
🎯 まとめ
✅ 達成内容
- XAMPPとLaravelでMiniCRUDアプリを構築
- モデル・コントローラ・ビューでCRUDを実現
- セッション・CSRF対策を理解
🚀 次のステップ
- ページネーション
- 検索機能
- 本番環境へのデプロイ(Laravel Forgeなど)
👉 これで「Laravelってこうやって動くんだ!」を最短で体験!