Laravel 11: 처음부터 완전한 애플리케이션 구축하기
Laravel 11로 인증, REST API, Eloquent ORM, 배포까지 완전한 애플리케이션을 구축하는 종합 가이드입니다. 실용적인 코드 예제와 함께 설명합니다.

Laravel 11은 간소화된 아키텍처와 최적화된 성능으로 모던 PHP 개발의 기준을 새롭게 정립합니다. 이번 메이저 릴리스에서는 많은 기본 설정 파일이 제거되었고, 더 가벼운 구조가 도입되었으며, 개발자 경험이 크게 향상되었습니다. 본 가이드에서는 태스크 관리 애플리케이션의 구축 과정을 설치부터 배포까지 단계별로 다룹니다.
Laravel 11은 미니멀리스트 구조를 채택했습니다. Kernel 파일이 제거되고, 설정이 bootstrap/app.php로 통합되었으며, app/ 디렉토리가 깔끔해졌습니다. PHP 8.2 이상이 필수이며, SQLite가 기본 통합되어 빠르게 개발을 시작할 수 있습니다.
Installation and Project Setup
Laravel 11은 Composer 또는 Laravel 인스톨러를 통해 설치할 수 있습니다. 새로운 프로젝트 구조는 더 가벼워졌으며, 초기에 관리해야 할 설정 파일이 적습니다.
# terminal
# Install the Laravel installer (recommended)
composer global require laravel/installer
# Create a new Laravel 11 project
laravel new task-manager
# Or directly with Composer
composer create-project laravel/laravel task-manager
# Navigate to the project
cd task-manager인스톨러에서는 스타터 킷(Breeze, Jetstream), 테스트 프레임워크(Pest, PHPUnit), 데이터베이스 등 여러 가지 옵션을 대화형으로 선택할 수 있습니다.
# terminal
# Start the development server
php artisan serve
# Server starts at http://localhost:8000데이터베이스 설정
Laravel 11은 기본적으로 SQLite를 사용하며, 개발 환경에 적합합니다. 프로덕션 애플리케이션에서는 MySQL 또는 PostgreSQL 설정을 .env 파일에서 진행합니다.
# .env
# MySQL configuration
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=task_manager
DB_USERNAME=root
DB_PASSWORD=secret
# PostgreSQL configuration (alternative)
# DB_CONNECTION=pgsql
# DB_HOST=127.0.0.1
# DB_PORT=5432
# DB_DATABASE=task_manager
# DB_USERNAME=postgres
# DB_PASSWORD=secret데이터베이스 연결 확인은 Artisan 명령어를 사용합니다.
# terminal
# Verify database connection
php artisan db:show
# Run default migrations
php artisan migrateCreating Models and Migrations
Eloquent ORM은 표현력 있는 모델을 통해 데이터 조작을 단순화합니다. make:model 명령어로 모델, 마이그레이션, 컨트롤러, 팩토리를 한 번에 생성할 수 있습니다.
# terminal
# Generate Task model with migration, factory, seeder, and controller
php artisan make:model Task -mfsc
# -m : migration
# -f : factory
# -s : seeder
# -c : controller이 명령어는 태스크 관리에 필요한 4개의 핵심 파일을 생성합니다.
<?php
// database/migrations/2026_01_14_000000_create_tasks_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration to create the tasks table
return new class extends Migration
{
public function up(): void
{
Schema::create('tasks', function (Blueprint $table) {
// Auto-incrementing primary key
$table->id();
// Relationship with the owner user
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
// Task title (required)
$table->string('title');
// Detailed description (optional)
$table->text('description')->nullable();
// Status: pending, in_progress, completed
$table->string('status')->default('pending');
// Priority: low, medium, high
$table->string('priority')->default('medium');
// Due date (optional)
$table->date('due_date')->nullable();
// Completion marker
$table->timestamp('completed_at')->nullable();
// Automatic timestamps (created_at, updated_at)
$table->timestamps();
// Soft deletes for trash functionality
$table->softDeletes();
// Indexes to optimize frequent queries
$table->index(['user_id', 'status']);
$table->index('due_date');
});
}
public function down(): void
{
Schema::dropIfExists('tasks');
}
};이 마이그레이션은 관계, 인덱스, 소프트 딜리트를 포함한 테이블 구조를 정의합니다. 소프트 딜리트를 통해 실수로 인한 데이터 손실을 방지할 수 있습니다.
<?php
// app/Models/Task.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Builder;
class Task extends Model
{
// Traits for advanced functionality
use HasFactory, SoftDeletes;
// Mass-assignable attributes
protected $fillable = [
'user_id',
'title',
'description',
'status',
'priority',
'due_date',
'completed_at',
];
// Automatic attribute casting
protected function casts(): array
{
return [
'due_date' => 'date',
'completed_at' => 'datetime',
];
}
// Constants for valid statuses
public const STATUS_PENDING = 'pending';
public const STATUS_IN_PROGRESS = 'in_progress';
public const STATUS_COMPLETED = 'completed';
// Constants for priorities
public const PRIORITY_LOW = 'low';
public const PRIORITY_MEDIUM = 'medium';
public const PRIORITY_HIGH = 'high';
// Relationship: a task belongs to a user
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
// Scope: pending tasks
public function scopePending(Builder $query): Builder
{
return $query->where('status', self::STATUS_PENDING);
}
// Scope: in-progress tasks
public function scopeInProgress(Builder $query): Builder
{
return $query->where('status', self::STATUS_IN_PROGRESS);
}
// Scope: completed tasks
public function scopeCompleted(Builder $query): Builder
{
return $query->where('status', self::STATUS_COMPLETED);
}
// Scope: overdue tasks
public function scopeOverdue(Builder $query): Builder
{
return $query->where('due_date', '<', now())
->whereNull('completed_at');
}
// Scope: tasks for a specific user
public function scopeForUser(Builder $query, int $userId): Builder
{
return $query->where('user_id', $userId);
}
// Accessor: check if task is overdue
public function getIsOverdueAttribute(): bool
{
return $this->due_date
&& $this->due_date->isPast()
&& !$this->completed_at;
}
// Method: mark as completed
public function markAsCompleted(): void
{
$this->update([
'status' => self::STATUS_COMPLETED,
'completed_at' => now(),
]);
}
}Task 모델은 Eloquent 스코프를 활용하여 읽기 쉽고 재사용 가능한 쿼리를 구현합니다. 상수로 상태와 우선순위의 유효한 값을 중앙에서 관리합니다.
SoftDeletes 트레이트는 deleted_at 컬럼을 추가합니다. 삭제된 태스크는 데이터베이스에서 제거되지 않고 삭제 표시만 됩니다. withTrashed()를 사용하면 삭제된 레코드도 쿼리에 포함시킬 수 있습니다.
Setting Up Authentication with Breeze
Laravel Breeze는 Blade 뷰 또는 API를 갖춘 완전한 인증 기능을 제공합니다. 몇 분이면 설치가 완료되며, 라우트, 컨트롤러, 뷰, 테스트가 모두 생성됩니다.
# terminal
# Install Laravel Breeze
composer require laravel/breeze --dev
# Install the Blade stack (traditional)
php artisan breeze:install blade
# Or for API only (SPA/mobile)
php artisan breeze:install api
# Compile assets
npm install && npm run build
# Run migrations (users, sessions tables, etc.)
php artisan migrateBreeze는 회원가입, 로그인, 비밀번호 재설정, 이메일 인증을 위한 인증 라우트, 컨트롤러, 뷰를 생성합니다.
<?php
// app/Models/User.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
// Relationship: a user owns multiple tasks
public function tasks(): HasMany
{
return $this->hasMany(Task::class);
}
// Shortcut: user's pending tasks
public function pendingTasks(): HasMany
{
return $this->tasks()->pending();
}
// Shortcut: user's overdue tasks
public function overdueTasks(): HasMany
{
return $this->tasks()->overdue();
}
}Laravel 면접 준비가 되셨나요?
인터랙티브 시뮬레이터, flashcards, 기술 테스트로 연습하세요.
Creating Controllers and Routes
컨트롤러는 HTTP 요청과 모델 사이의 비즈니스 로직을 조율하는 역할을 합니다. Laravel 11에서는 싱글 액션 컨트롤러 또는 RESTful 리소스 사용을 권장합니다.
<?php
// app/Http/Controllers/TaskController.php
namespace App\Http\Controllers;
use App\Models\Task;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;
use Illuminate\Support\Facades\Gate;
class TaskController extends Controller
{
// List tasks for the authenticated user
public function index(Request $request): View
{
// Retrieve tasks with optional filtering
$tasks = $request->user()
->tasks()
->when($request->status, fn($q, $status) => $q->where('status', $status))
->when($request->priority, fn($q, $priority) => $q->where('priority', $priority))
->orderBy('due_date')
->orderBy('priority', 'desc')
->paginate(15);
return view('tasks.index', compact('tasks'));
}
// Creation form
public function create(): View
{
return view('tasks.create');
}
// Store a new task
public function store(Request $request): RedirectResponse
{
// Validate incoming data
$validated = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string|max:5000',
'priority' => 'required|in:low,medium,high',
'due_date' => 'nullable|date|after_or_equal:today',
]);
// Create the task linked to the user
$request->user()->tasks()->create($validated);
return redirect()
->route('tasks.index')
->with('success', 'Task created successfully.');
}
// Display a task
public function show(Task $task): View
{
// Verify user ownership
Gate::authorize('view', $task);
return view('tasks.show', compact('task'));
}
// Edit form
public function edit(Task $task): View
{
Gate::authorize('update', $task);
return view('tasks.edit', compact('task'));
}
// Update a task
public function update(Request $request, Task $task): RedirectResponse
{
Gate::authorize('update', $task);
$validated = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string|max:5000',
'status' => 'required|in:pending,in_progress,completed',
'priority' => 'required|in:low,medium,high',
'due_date' => 'nullable|date',
]);
// Update completed_at if status = completed
if ($validated['status'] === Task::STATUS_COMPLETED && !$task->completed_at) {
$validated['completed_at'] = now();
}
$task->update($validated);
return redirect()
->route('tasks.index')
->with('success', 'Task updated.');
}
// Delete a task
public function destroy(Task $task): RedirectResponse
{
Gate::authorize('delete', $task);
$task->delete();
return redirect()
->route('tasks.index')
->with('success', 'Task deleted.');
}
// Mark as completed (quick action)
public function complete(Task $task): RedirectResponse
{
Gate::authorize('update', $task);
$task->markAsCompleted();
return back()->with('success', 'Task completed!');
}
}이 컨트롤러는 인가에 Gate를, 유효성 검사에 내장 기능을, 라우트 모델 바인딩을 활용하여 간결하고 안전한 코드를 구현합니다.
라우트 정의
라우트는 URL을 정의하고 컨트롤러 액션과 연결합니다. Laravel 11에서는 라우트가 routes/web.php에 집중됩니다.
<?php
// routes/web.php
use App\Http\Controllers\TaskController;
use App\Http\Controllers\ProfileController;
use Illuminate\Support\Facades\Route;
// Public homepage
Route::get('/', function () {
return view('welcome');
});
// Routes protected by authentication
Route::middleware(['auth', 'verified'])->group(function () {
// Dashboard with statistics
Route::get('/dashboard', function () {
$user = auth()->user();
return view('dashboard', [
'totalTasks' => $user->tasks()->count(),
'pendingTasks' => $user->tasks()->pending()->count(),
'completedTasks' => $user->tasks()->completed()->count(),
'overdueTasks' => $user->tasks()->overdue()->count(),
]);
})->name('dashboard');
// RESTful routes for tasks
Route::resource('tasks', TaskController::class);
// Quick action to complete a task
Route::patch('/tasks/{task}/complete', [TaskController::class, 'complete'])
->name('tasks.complete');
// Profile routes (generated by Breeze)
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
});
// Authentication routes (generated by Breeze)
require __DIR__.'/auth.php';Route::resource() 메서드는 index, create, store, show, edit, update, destroy 등 7개의 표준 RESTful 라우트를 자동으로 생성합니다.
Setting Up Authorization Policies
폴리시는 각 모델의 인가 로직을 중앙에서 관리합니다. 어떤 사용자가 리소스에 대해 어떤 작업을 수행할 수 있는지 정의합니다.
# terminal
# Generate the policy for Task
php artisan make:policy TaskPolicy --model=Task<?php
// app/Policies/TaskPolicy.php
namespace App\Policies;
use App\Models\Task;
use App\Models\User;
class TaskPolicy
{
// Check before all methods
// Returning true bypasses all checks (admin)
public function before(User $user, string $ability): ?bool
{
if ($user->is_admin) {
return true;
}
return null; // Continue to specific methods
}
// Can view the list of tasks
public function viewAny(User $user): bool
{
return true; // Any authenticated user
}
// Can view a specific task
public function view(User $user, Task $task): bool
{
return $user->id === $task->user_id;
}
// Can create a task
public function create(User $user): bool
{
return true;
}
// Can update a task
public function update(User $user, Task $task): bool
{
return $user->id === $task->user_id;
}
// Can delete a task
public function delete(User $user, Task $task): bool
{
return $user->id === $task->user_id;
}
// Can restore a soft-deleted task
public function restore(User $user, Task $task): bool
{
return $user->id === $task->user_id;
}
// Can permanently delete
public function forceDelete(User $user, Task $task): bool
{
return $user->id === $task->user_id;
}
}Laravel은 명명 규칙에 따라 폴리시를 자동으로 검색합니다. TaskPolicy는 Task 모델에 자동으로 적용됩니다.
폴리시는 보안의 핵심입니다. 폴리시가 없으면 사용자가 URL을 조작하여 다른 사용자의 태스크에 접근할 수 있습니다. 리소스 소유권 확인은 반드시 구현해야 합니다.
Building a REST API
Laravel은 전용 라우트, JSON 리소스, Sanctum 인증을 통해 RESTful API 생성을 단순화합니다.
# terminal
# Install Sanctum (included by default since Laravel 11)
php artisan install:api
# This command:
# - Publishes Sanctum migrations
# - Adds the HasApiTokens trait to the User model
# - Configures API routes<?php
// app/Http/Controllers/Api/TaskController.php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\TaskResource;
use App\Http\Resources\TaskCollection;
use App\Models\Task;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
class TaskController extends Controller
{
// Paginated list of tasks
public function index(Request $request): AnonymousResourceCollection
{
$tasks = $request->user()
->tasks()
->when($request->status, fn($q, $s) => $q->where('status', $s))
->when($request->priority, fn($q, $p) => $q->where('priority', $p))
->when($request->boolean('overdue'), fn($q) => $q->overdue())
->latest()
->paginate($request->input('per_page', 15));
return TaskResource::collection($tasks);
}
// Create a task
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string|max:5000',
'priority' => 'required|in:low,medium,high',
'due_date' => 'nullable|date|after_or_equal:today',
]);
$task = $request->user()->tasks()->create($validated);
return response()->json([
'message' => 'Task created successfully.',
'data' => new TaskResource($task),
], 201);
}
// Display a task
public function show(Task $task): TaskResource
{
$this->authorize('view', $task);
return new TaskResource($task);
}
// Update a task
public function update(Request $request, Task $task): TaskResource
{
$this->authorize('update', $task);
$validated = $request->validate([
'title' => 'sometimes|required|string|max:255',
'description' => 'nullable|string|max:5000',
'status' => 'sometimes|required|in:pending,in_progress,completed',
'priority' => 'sometimes|required|in:low,medium,high',
'due_date' => 'nullable|date',
]);
if (isset($validated['status'])
&& $validated['status'] === Task::STATUS_COMPLETED
&& !$task->completed_at) {
$validated['completed_at'] = now();
}
$task->update($validated);
return new TaskResource($task->fresh());
}
// Delete a task
public function destroy(Task $task): JsonResponse
{
$this->authorize('delete', $task);
$task->delete();
return response()->json([
'message' => 'Task deleted successfully.',
]);
}
}API 리소스를 활용한 데이터 변환
API 리소스는 Eloquent 모델을 구조화된 JSON 응답으로 변환하며, 노출되는 데이터를 정밀하게 제어합니다.
<?php
// app/Http/Resources/TaskResource.php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class TaskResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'status' => $this->status,
'priority' => $this->priority,
'due_date' => $this->due_date?->format('Y-m-d'),
'is_overdue' => $this->is_overdue,
'completed_at' => $this->completed_at?->toISOString(),
'created_at' => $this->created_at->toISOString(),
'updated_at' => $this->updated_at->toISOString(),
// Conditional inclusion of the user
'user' => $this->whenLoaded('user', fn() => [
'id' => $this->user->id,
'name' => $this->user->name,
]),
];
}
}Sanctum 인증 기반 API 라우트
<?php
// routes/api.php
use App\Http\Controllers\Api\TaskController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
// Route to retrieve the authenticated user
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
// API routes protected by Sanctum
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('tasks', TaskController::class);
// Dashboard statistics
Route::get('/dashboard/stats', function (Request $request) {
$user = $request->user();
return response()->json([
'total' => $user->tasks()->count(),
'pending' => $user->tasks()->pending()->count(),
'in_progress' => $user->tasks()->inProgress()->count(),
'completed' => $user->tasks()->completed()->count(),
'overdue' => $user->tasks()->overdue()->count(),
]);
});
});Automated Testing with Pest
Laravel 11은 기본적으로 Pest PHP를 통합하고 있으며, 우아하고 표현력 있는 테스트 프레임워크입니다. 테스트를 통해 수정 후에도 애플리케이션이 올바르게 동작하는지 보장할 수 있습니다.
<?php
// tests/Feature/TaskTest.php
use App\Models\Task;
use App\Models\User;
// Test: a user can view their tasks
test('user can view their tasks', function () {
$user = User::factory()->create();
$tasks = Task::factory()->count(5)->for($user)->create();
$response = $this->actingAs($user)->get('/tasks');
$response->assertOk();
$response->assertViewHas('tasks');
});
// Test: a user can create a task
test('user can create a task', function () {
$user = User::factory()->create();
$response = $this->actingAs($user)->post('/tasks', [
'title' => 'New task',
'description' => 'Task description',
'priority' => 'high',
'due_date' => now()->addDays(7)->format('Y-m-d'),
]);
$response->assertRedirect('/tasks');
$this->assertDatabaseHas('tasks', [
'user_id' => $user->id,
'title' => 'New task',
'priority' => 'high',
]);
});
// Test: title validation required
test('task title is required', function () {
$user = User::factory()->create();
$response = $this->actingAs($user)->post('/tasks', [
'title' => '',
'priority' => 'medium',
]);
$response->assertSessionHasErrors('title');
});
// Test: a user cannot view another user's task
test('user cannot view another users task', function () {
$user = User::factory()->create();
$otherUser = User::factory()->create();
$task = Task::factory()->for($otherUser)->create();
$response = $this->actingAs($user)->get("/tasks/{$task->id}");
$response->assertForbidden();
});
// Test: mark a task as completed
test('user can complete a task', function () {
$user = User::factory()->create();
$task = Task::factory()->for($user)->create(['status' => 'pending']);
$response = $this->actingAs($user)->patch("/tasks/{$task->id}/complete");
$response->assertRedirect();
$task->refresh();
expect($task->status)->toBe('completed');
expect($task->completed_at)->not->toBeNull();
});
// API test: retrieve tasks
test('api returns paginated tasks', function () {
$user = User::factory()->create();
Task::factory()->count(20)->for($user)->create();
$response = $this->actingAs($user, 'sanctum')
->getJson('/api/tasks?per_page=10');
$response->assertOk()
->assertJsonCount(10, 'data')
->assertJsonStructure([
'data' => [
'*' => ['id', 'title', 'status', 'priority', 'due_date'],
],
'links',
'meta',
]);
});Pest를 사용한 테스트 실행 방법은 다음과 같습니다.
# terminal
# Run all tests
php artisan test
# Tests with code coverage
php artisan test --coverage
# Tests for a specific file
php artisan test tests/Feature/TaskTest.php
# Parallel tests (faster)
php artisan test --parallelProduction Optimizations
배포 전에 몇 가지 최적화를 통해 Laravel 애플리케이션의 성능을 향상시킬 수 있습니다.
# terminal
# Cache configuration
php artisan config:cache
# Cache routes
php artisan route:cache
# Cache views
php artisan view:cache
# Optimize Composer autoloader
composer install --optimize-autoloader --no-dev
# Generate asset manifest
npm run build프로덕션 .env 파일 설정
# .env.production
APP_NAME="Task Manager"
APP_ENV=production
APP_DEBUG=false
APP_URL=https://taskmanager.example.com
# Cache and session via Redis (recommended)
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
# Database
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=task_manager_prod
DB_USERNAME=app_user
DB_PASSWORD=strong_password_here
# Mail
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=postmaster@taskmanager.example.com
MAIL_PASSWORD=secret
MAIL_ENCRYPTION=tls.env 파일을 Git 저장소에 커밋해서는 안 됩니다. .env.example을 템플릿으로 사용하고, 민감한 변수는 프로덕션 서버에 직접 설정하거나 시크릿 매니저를 통해 관리해야 합니다.
Conclusion
Laravel 11은 간소화된 구조와 지능적인 컨벤션으로 모던 PHP 개발을 크게 단순화합니다. 본 가이드에서는 완전한 애플리케이션 구축의 기본을 다루었습니다. Eloquent 모델, 인증, RESTful 컨트롤러, 인가 폴리시, Sanctum API, 자동화된 테스트를 포괄적으로 설명했습니다.
고품질 Laravel 애플리케이션을 위한 체크리스트
- 모든 스키마 변경에 마이그레이션을 사용할 것
- 폴리시를 구현하여 리소스 접근을 보호할 것
- 컨트롤러에서 모든 사용자 입력을 유효성 검사할 것
- API 리소스로 노출 데이터를 제어할 것
- 핵심 기능에 대한 테스트를 작성할 것
- 배포 전 캐시와 최적화를 설정할 것
- 민감한 환경 변수를 보호할 것
연습을 시작하세요!
면접 시뮬레이터와 기술 테스트로 지식을 테스트하세요.
Laravel 생태계는 리액티브 인터페이스를 위한 Livewire, 큐 관리를 위한 Horizon, 뛰어난 성능을 위한 Octane 등 다양한 패키지와 함께 계속 발전하고 있습니다. 이러한 기본기를 마스터하면 견고하고 유지보수 가능한 PHP 애플리케이션을 구축할 수 있습니다.
태그
공유

