편집을 취소할 수 있습니다. 이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 게시해주세요.
최신판 | 당신의 편집 | ||
11번째 줄: | 11번째 줄: | ||
==설치== | ==설치== | ||
[[Laravel Homestead|Homestead 가상머신]]을 사용하거나 선택한 로컬 PHP 환경을 사용하여 프레임워크를 실행할 수 있습니다. | 우선, Laravel 프레임워크을 새로 설치해야 합니다. [[Laravel Homestead|Homestead 가상머신]]을 사용하거나 선택한 로컬 PHP 환경을 사용하여 프레임워크를 실행할 수 있습니다. 로컬 환경이 준비되면 Composer를 사용하여 Laravel 프레임워크를 설치할 수 있습니다: | ||
환경이 준비되면 Composer를 사용하여 Laravel 프레임워크를 설치할 수 있습니다: | |||
<syntaxhighlight lang='bash'> | <syntaxhighlight lang='bash'> | ||
39번째 줄: | 18번째 줄: | ||
<syntaxhighlight lang='console'> | <syntaxhighlight lang='console'> | ||
testuser@localhost:~$ composer create-project laravel/laravel quickstart --prefer-dist | |||
Creating a "laravel/laravel" project at "./quickstart" | Creating a "laravel/laravel" project at "./quickstart" | ||
Installing laravel/laravel (v11.1.1) | Installing laravel/laravel (v11.1.1) | ||
... | ... | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<syntaxhighlight lang='console'> | <syntaxhighlight lang='console'> | ||
testuser@localhost:~$ cd quickstart/ | |||
testuser@localhost:~/quickstart$ find app/ | grep .php | |||
app/Providers/AppServiceProvider.php | app/Providers/AppServiceProvider.php | ||
app/Http/Controllers/Controller.php | app/Http/Controllers/Controller.php | ||
app/Models/User.php | app/Models/User.php | ||
</syntaxhighlight> | </syntaxhighlight> | ||
'''참고''': [[composer create-project laravel/laravel quickstart --prefer-dist]] | '''참고''': [[composer create-project laravel/laravel quickstart --prefer-dist]] | ||
==데이터베이스 준비== | ==데이터베이스 준비== | ||
97번째 줄: | 43번째 줄: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<syntaxhighlight lang='console'> | <syntaxhighlight lang='console'> | ||
$ php artisan make:migration create_tasks_table --create=tasks | testuser@localhost:~/quickstart$ php artisan make:migration create_tasks_table --create=tasks | ||
INFO Migration [database/migrations/ | INFO Migration [database/migrations/2024_06_15_161234_create_tasks_table.php] created successfully. | ||
</syntaxhighlight> | </syntaxhighlight> | ||
마이그레이션 파일은 프로젝트의 <code>database/migrations</code> 디렉토리에 생성됩니다. 아마도 <code>make:migration</code> 명령어가 이미 자동 증가 ID와 타임스탬프를 마이그레이션 파일에 추가한 것을 보셨을 것입니다. 이 파일을 편집하여 작업 이름을 위한 <code>name</code> 문자열 컬럼을 추가해봅시다: | 마이그레이션 파일은 프로젝트의 <code>database/migrations</code> 디렉토리에 생성됩니다. 아마도 <code>make:migration</code> 명령어가 이미 자동 증가 ID와 타임스탬프를 마이그레이션 파일에 추가한 것을 보셨을 것입니다. 이 파일을 편집하여 작업 이름을 위한 <code>name</code> 문자열 컬럼을 추가해봅시다: | ||
<syntaxhighlight lang='php' highlight='16'> | <syntaxhighlight lang='php' highlight='16'> | ||
<?php | <?php | ||
142번째 줄: | 87번째 줄: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<syntaxhighlight lang='console'> | <syntaxhighlight lang='console'> | ||
$ php artisan migrate | testuser@localhost:~/quickstart$ php artisan migrate | ||
INFO Running migrations. | INFO Running migrations. | ||
2024_06_15_161234_create_tasks_table ................................................................................................. 6.75ms DONE | |||
</syntaxhighlight> | </syntaxhighlight> | ||
159번째 줄: | 104번째 줄: | ||
php artisan make:model Task | php artisan make:model Task | ||
</syntaxhighlight> | </syntaxhighlight> | ||
모델은 애플리케이션의 <code>app | 모델은 애플리케이션의 <code>app</code> 디렉토리에 배치됩니다. 기본적으로 모델 클래스는 비어 있습니다. Eloquent 모델에 어떤 테이블과 대응되는지 명시적으로 알릴 필요는 없습니다. 왜냐하면 Eloquent는 모델 이름의 복수형을 데이터베이스 테이블로 가정하기 때문입니다. 따라서, <code>Task</code> 모델은 <code>tasks</code> 데이터베이스 테이블과 대응되는 것으로 간주됩니다. 빈 모델은 다음과 같이 생겼습니다: | ||
<syntaxhighlight lang='php'> | <syntaxhighlight lang='php'> | ||
<?php | <?php | ||
namespace App | namespace App; | ||
use Illuminate\Database\Eloquent\Model; | use Illuminate\Database\Eloquent\Model; | ||
class Task extends Model | class Task extends Model | ||
{ | { | ||
// | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
187번째 줄: | 124번째 줄: | ||
==라우팅== | ==라우팅== | ||
===라우트 스터빙=== | ===라우트 스터빙=== | ||
다음으로, 애플리케이션에 몇 가지 라우트를 추가할 준비가 되었습니다. 라우트는 URL을 컨트롤러나 사용자가 특정 페이지에 액세스할 때 실행해야 하는 익명 함수로 연결하는 데 사용됩니다. 기본적으로 모든 Laravel 라우트는 새로운 프로젝트에 포함된 <code>routes</code> | 다음으로, 애플리케이션에 몇 가지 라우트를 추가할 준비가 되었습니다. 라우트는 URL을 컨트롤러나 사용자가 특정 페이지에 액세스할 때 실행해야 하는 익명 함수로 연결하는 데 사용됩니다. 기본적으로 모든 Laravel 라우트는 새로운 프로젝트에 포함된 <code>app/Http/routes.php</code> 파일에 정의됩니다. | ||
이 애플리케이션에서는 최소한 세 개의 라우트가 필요하다는 것을 알고 있습니다. 모든 태스크 목록을 표시하는 라우트, 새로운 태스크를 추가하는 라우트, 기존 태스크를 삭제하는 라우트가 필요합니다. 따라서, <code>routes | 이 애플리케이션에서는 최소한 세 개의 라우트가 필요하다는 것을 알고 있습니다. 모든 태스크 목록을 표시하는 라우트, 새로운 태스크를 추가하는 라우트, 기존 태스크를 삭제하는 라우트가 필요합니다. 따라서, <code>app/Http/routes.php</code> 파일에 이러한 모든 라우트를 스터빙해 보겠습니다: | ||
<syntaxhighlight lang='php'> | <syntaxhighlight lang='php'> | ||
<?php | <?php | ||
use Illuminate\ | use App\Task; | ||
use Illuminate\Http\Request; | |||
/** | /** | ||
* | * 작업 대시보드 표시 | ||
*/ | */ | ||
Route::get('/', function () { | Route::get('/', function () { | ||
205번째 줄: | 142번째 줄: | ||
/** | /** | ||
* | * 새 작업 추가 | ||
*/ | */ | ||
Route::post('/task', function (Request $request) { | Route::post('/task', function (Request $request) { | ||
212번째 줄: | 149번째 줄: | ||
/** | /** | ||
* | * 작업 삭제 | ||
*/ | */ | ||
Route::delete('/task/{task}', function (Task $task) { | Route::delete('/task/{task}', function (Task $task) { | ||
218번째 줄: | 155번째 줄: | ||
}); | }); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
{{NOTE}} | |||
만약 여러분의 Laravel 버전에 이미 기본 라우트 파일을 <code>web</code> 미들웨어 그룹 내에 포함하는 <code>RouteServiceProvider</code>가 있다면, <code>routes.php</code> 파일에 그룹을 수동으로 추가할 필요가 없습니다. | |||
{{/NOTE}} | |||
===뷰 표시하기=== | ===뷰 표시하기=== | ||
224번째 줄: | 165번째 줄: | ||
Laravel에서는 모든 HTML 템플릿이 <code>resources/views</code> 디렉토리에 저장되며, <code>view</code> 헬퍼를 사용하여 해당 라우트에서 이 템플릿 중 하나를 반환할 수 있습니다: | Laravel에서는 모든 HTML 템플릿이 <code>resources/views</code> 디렉토리에 저장되며, <code>view</code> 헬퍼를 사용하여 해당 라우트에서 이 템플릿 중 하나를 반환할 수 있습니다: | ||
<syntaxhighlight lang='php'> | |||
<syntaxhighlight lang='php | |||
Route::get('/', function () { | Route::get('/', function () { | ||
return view('tasks'); | return view('tasks'); | ||
245번째 줄: | 185번째 줄: | ||
우리의 <code>app.blade.php</code> 뷰는 다음과 같이 생겼습니다: | 우리의 <code>app.blade.php</code> 뷰는 다음과 같이 생겼습니다: | ||
<syntaxhighlight lang='php'> | <syntaxhighlight lang='php'> | ||
<!-- resources/views/layouts/app.blade.php --> | |||
<!DOCTYPE html> | <!DOCTYPE html> | ||
<html lang="en"> | <html lang="en"> | ||
<head> | <head> | ||
<title>Laravel Quickstart - Basic</title> | <title>Laravel Quickstart - Basic</title> | ||
< | |||
<!-- CSS And JavaScript --> | |||
</head> | </head> | ||
<body> | <body> | ||
< | <div class="container"> | ||
< | <nav class="navbar navbar-default"> | ||
<!-- Navbar Contents --> | |||
</ | </nav> | ||
</ | </div> | ||
@yield('content') | @yield('content') | ||
273번째 줄: | 215번째 줄: | ||
Bootstrap CSS 보일러플레이트 일부는 생략하고 중요한 부분만 다루겠습니다. 이 애플리케이션의 전체 소스코드는 [https://github.com/laravel/quickstart-basic GitHub]에서 다운로드할 수 있습니다: | Bootstrap CSS 보일러플레이트 일부는 생략하고 중요한 부분만 다루겠습니다. 이 애플리케이션의 전체 소스코드는 [https://github.com/laravel/quickstart-basic GitHub]에서 다운로드할 수 있습니다: | ||
<syntaxhighlight lang='php'> | <syntaxhighlight lang='php'> | ||
<!-- resources/views/tasks.blade.php --> | |||
@extends('layouts.app') | @extends('layouts.app') | ||
280번째 줄: | 223번째 줄: | ||
<!-- Bootstrap Boilerplate... --> | <!-- Bootstrap Boilerplate... --> | ||
<div class="panel-body"> | |||
<!-- Display Validation Errors --> | |||
@include('common.errors') | |||
<!-- New Task Form --> | |||
<form action="{{ url('task') }}" method="POST" class="form-horizontal"> | |||
{{ csrf_field() }} | |||
<!-- | <!-- Task Name --> | ||
< | <div class="form-group"> | ||
<label for="task" class="col-sm-3 control-label">Task</label> | |||
<div class="col-sm-6"> | |||
<div class=" | <input type="text" name="name" id="task-name" class="form-control"> | ||
<input type="text" name="name" id="task" class="form-control"> | |||
</div> | </div> | ||
</div> | |||
<!-- Add Task Button --> | |||
<button type="submit" class="btn btn- | <div class="form-group"> | ||
<div class="col-sm-offset-3 col-sm-6"> | |||
</ | <button type="submit" class="btn btn-default"> | ||
</ | <i class="fa fa-plus"></i> Add Task | ||
</ | </button> | ||
</div> | |||
</div> | |||
</form> | |||
</div> | </div> | ||
318번째 줄: | 263번째 줄: | ||
이제 애플리케이션에 대한 기본 레이아웃과 뷰를 정의했습니다. 우리는 이 뷰를 <code>/</code> 라우트에서 다음과 같이 반환하고 있습니다: | 이제 애플리케이션에 대한 기본 레이아웃과 뷰를 정의했습니다. 우리는 이 뷰를 <code>/</code> 라우트에서 다음과 같이 반환하고 있습니다: | ||
<syntaxhighlight lang='php'> | <syntaxhighlight lang='php'> | ||
Route::get('/', function () { | Route::get('/', function () { | ||
329번째 줄: | 273번째 줄: | ||
==태스크 추가== | ==태스크 추가== | ||
===유효성 검증=== | ===유효성 검증=== | ||
이제 뷰에 폼을 만들었으니, <code>routes | 이제 뷰에 폼을 만들었으니, <code>app/Http/routes.php</code>의 <code>POST /task</code> 라우트에 코드를 추가하여 들어오는 폼 입력을 유효성 검증하고 새로운 작업을 생성해야 합니다. 먼저, 입력을 검증해 봅시다. | ||
이 폼의 경우, <code>name</code> 필드를 필수로 하고, <code>255</code>자 이하로 제한할 것입니다. | 이 폼의 경우, <code>name</code> 필드를 필수로 하고, <code>255</code>자 이하로 제한할 것입니다. 검사에 실패하면 사용자를 <code>/</code> URL로 리디렉션하고, 이전 입력과 오류를 [[Laravel 세션|세션]]에 플래시할 것입니다. 입력을 세션에 플래시하면 검증 오류가 있을 때에도 사용자의 입력을 유지할 수 있습니다: | ||
<syntaxhighlight lang='php'> | <syntaxhighlight lang='php'> | ||
Route::post('/task', function () { | Route::post('/task', function (Request $request) { | ||
$validator = Validator::make( | $validator = Validator::make($request->all(), [ | ||
'name' => 'required|max:255', | 'name' => 'required|max:255', | ||
]); | ]); | ||
346번째 줄: | 289번째 줄: | ||
} | } | ||
// | // 태스크 생성... | ||
}); | }); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
355번째 줄: | 298번째 줄: | ||
뷰에서 <code>@include('common.errors')</code> 지시어를 사용하여 폼의 검증 오류를 렌더링했던 것을 기억하십시오. <code>common.errors</code>는 모든 페이지에서 동일한 형식으로 검증 오류를 쉽게 보여줄 수 있게 합니다. 이제 이 뷰의 내용을 정의해 봅시다: | 뷰에서 <code>@include('common.errors')</code> 지시어를 사용하여 폼의 검증 오류를 렌더링했던 것을 기억하십시오. <code>common.errors</code>는 모든 페이지에서 동일한 형식으로 검증 오류를 쉽게 보여줄 수 있게 합니다. 이제 이 뷰의 내용을 정의해 봅시다: | ||
<syntaxhighlight lang='php'> | <syntaxhighlight lang='php'> | ||
<!-- resources/views/common/errors.blade.php --> | |||
@if (count($errors) > 0) | @if (count($errors) > 0) | ||
<!-- Form Error List --> | <!-- Form Error List --> | ||
378번째 줄: | 322번째 줄: | ||
입력 검증이 처리되었으므로, 실제로 새 태스크를 생성하여 라우트를 계속 채워 나갑시다. 새 태스크가 생성되면 사용자를 <code>/</code> URL로 리디렉션합니다. 태스크를 생성하기 위해, 새로운 Eloquent 모델에 속성을 설정한 후 <code>save</code> 메소드를 사용할 수 있습니다: | 입력 검증이 처리되었으므로, 실제로 새 태스크를 생성하여 라우트를 계속 채워 나갑시다. 새 태스크가 생성되면 사용자를 <code>/</code> URL로 리디렉션합니다. 태스크를 생성하기 위해, 새로운 Eloquent 모델에 속성을 설정한 후 <code>save</code> 메소드를 사용할 수 있습니다: | ||
<syntaxhighlight lang='php'> | |||
<syntaxhighlight lang='php | Route::post('/task', function (Request $request) { | ||
Route::post('/task', function () { | $validator = Validator::make($request->all(), [ | ||
$validator = Validator::make( | |||
'name' => 'required|max:255', | 'name' => 'required|max:255', | ||
]); | ]); | ||
392번째 줄: | 335번째 줄: | ||
$task = new Task; | $task = new Task; | ||
$task->name = | $task->name = $request->name; | ||
$task->save(); | $task->save(); | ||
404번째 줄: | 347번째 줄: | ||
먼저, <code>/</code> 라우트를 수정하여 모든 기존 태스크를 뷰에 전달해야 합니다. <code>view</code> 함수는 배열 형태의 두 번째 인수를 받아들여 뷰에서 사용할 수 있는 데이터를 전달하며, 배열의 각 키는 뷰 내에서 변수가 됩니다: | 먼저, <code>/</code> 라우트를 수정하여 모든 기존 태스크를 뷰에 전달해야 합니다. <code>view</code> 함수는 배열 형태의 두 번째 인수를 받아들여 뷰에서 사용할 수 있는 데이터를 전달하며, 배열의 각 키는 뷰 내에서 변수가 됩니다: | ||
<syntaxhighlight lang='php'> | |||
<syntaxhighlight lang='php | |||
Route::get('/', function () { | Route::get('/', function () { | ||
$tasks = Task::orderBy('created_at', 'asc')->get(); | $tasks = Task::orderBy('created_at', 'asc')->get(); | ||
425번째 줄: | 359번째 줄: | ||
데이터가 전달되면, <code>tasks.blade.php</code> 뷰에서 태스크를 순회하여 테이블에 태스크를 표시할 수 있습니다. <code>@foreach</code> Blade 구조는 간결한 루프를 작성할 수 있게 해주며, 이는 빠른 순수 PHP 코드로 컴파일됩니다: | 데이터가 전달되면, <code>tasks.blade.php</code> 뷰에서 태스크를 순회하여 테이블에 태스크를 표시할 수 있습니다. <code>@foreach</code> Blade 구조는 간결한 루프를 작성할 수 있게 해주며, 이는 빠른 순수 PHP 코드로 컴파일됩니다: | ||
<syntaxhighlight lang='php'> | <syntaxhighlight lang='php'> | ||
@extends('layouts.app') | @extends('layouts.app') | ||
@section('content') | @section('content') | ||
<!-- | <!-- 태스크 생성 폼... --> | ||
<!-- | <!-- 현재 태스크들 --> | ||
@if (count($tasks) > 0) | @if (count($tasks) > 0) | ||
<div class=" | <div class="panel panel-default"> | ||
<div class=" | <div class="panel-heading"> | ||
Current Tasks | Current Tasks | ||
</div> | </div> | ||
<div class=" | <div class="panel-body"> | ||
<table class="table table-striped"> | <table class="table table-striped task-table"> | ||
<!-- | <!-- 테이블 헤더 --> | ||
<thead> | <thead> | ||
<th>Task</th> | <th>Task</th> | ||
<th> </th> | <th> </th> | ||
</thead> | </thead> | ||
<!-- | <!-- 테이블 바디 --> | ||
<tbody> | <tbody> | ||
@foreach ($tasks as $task) | @foreach ($tasks as $task) | ||
<tr> | <tr> | ||
<!-- | <!-- 태스크 이름 --> | ||
<td class="table-text"> | <td class="table-text"> | ||
<div>{{ $task->name }}</div> | <div>{{ $task->name }}</div> | ||
</td> | </td> | ||
<td> | <td> | ||
<!-- TODO: | <!-- TODO: 삭제 버튼 --> | ||
</td> | </td> | ||
</tr> | </tr> | ||
476번째 줄: | 409번째 줄: | ||
삭제 버튼을 추가해야 할 곳에 "TODO" 메모를 남겼습니다. 이제 <code>tasks.blade.php</code> 뷰의 태스크 목록 각 행에 삭제 버튼을 추가하겠습니다. 각 태스크에 대해 단일 버튼 폼을 생성할 것입니다. 버튼을 클릭하면 애플리케이션에 <code>DELETE /task</code> 요청이 전송됩니다. | 삭제 버튼을 추가해야 할 곳에 "TODO" 메모를 남겼습니다. 이제 <code>tasks.blade.php</code> 뷰의 태스크 목록 각 행에 삭제 버튼을 추가하겠습니다. 각 태스크에 대해 단일 버튼 폼을 생성할 것입니다. 버튼을 클릭하면 애플리케이션에 <code>DELETE /task</code> 요청이 전송됩니다. | ||
<syntaxhighlight lang='php'> | |||
<syntaxhighlight lang='php | <tr> | ||
<!-- 태스크 이름 --> | |||
<td class="table-text"> | |||
<div>{{ $task->name }}</div> | |||
</td> | |||
<!-- 삭제 버튼 --> | |||
<td> | |||
<form action="{{ url('task/'.$task->id) }}" method="POST"> | |||
{{ csrf_field() }} | |||
{{ method_field('DELETE') }} | |||
<button type="submit" class="btn btn-danger"> | |||
<i class="fa fa-trash"></i> Delete | |||
</button> | |||
</form> | |||
</td> | |||
</tr> | |||
</syntaxhighlight> | </syntaxhighlight> | ||
512번째 줄: | 444번째 줄: | ||
라우트 콜백에서는, <code>delete</code> 메소드를 사용하여 레코드를 삭제합니다. 레코드가 삭제되면 사용자를 <code>/</code> URL로 리디렉션합니다: | 라우트 콜백에서는, <code>delete</code> 메소드를 사용하여 레코드를 삭제합니다. 레코드가 삭제되면 사용자를 <code>/</code> URL로 리디렉션합니다: | ||
<syntaxhighlight lang='php'> | <syntaxhighlight lang='php'> | ||
Route::delete('/task/{task}', function (Task $task) { | Route::delete('/task/{task}', function (Task $task) { |