최신판 |
당신의 편집 |
6번째 줄: |
6번째 줄: |
|
| |
|
| ==소개== | | ==소개== |
| 이 빠른 시작 가이드는 Laravel 프레임워크에 대한 기본 소개를 제공하며, 데이터베이스 마이그레이션, Eloquent ORM, 라우팅, 유효성 검증, 뷰, Blade 템플릿에 관한 내용을 포함하고 있습니다. Laravel 프레임워크나 PHP 프레임워크를 처음 접하는 경우에 좋은 시작점이 될 것입니다. 이미 Laravel이나 다른 PHP 프레임워크를 사용해본 경험이 있다면, [[Laravel 중급 태스크 목록|중급 수준의 빠른 시작 가이드]]를 참고하는 것이 좋습니다. | | 이 빠른 시작 가이드는 Laravel 프레임워크에 대한 기본적인 소개를 제공하며, 데이터베이스 마이그레이션, Eloquent ORM, 라우팅, 유효성검사, 뷰, Blade 템플릿에 관한 내용을 포함하고 있습니다. Laravel 프레임워크나 PHP 프레임워크를 처음 접하는 경우에 좋은 시작점이 될 것입니다. 이미 Laravel이나 다른 PHP 프레임워크를 사용해본 경험이 있다면, [[Laravel 중급 태스크 목록|중급 수준의 빠른 시작 가이드]]를 참고하는 것이 좋습니다. |
|
| |
|
| Laravel의 기본 기능들을 샘플로 다루어 보기 위해, 태스크들을 다루는 태스크 목록 애플리케이션을 만들어 보겠습니다. 즉, 전형적인 "할 일" 목록 예제를 다루게 됩니다. 이 프로젝트의 완성된 소스코드는 [https://github.com/laravel/quickstart-basic GitHub에서 확인]할 수 있습니다. | | Laravel의 기본 기능들을 샘플링하기 위해, 우리가 수행하려는 모든 태스크을 추적하는 간단한 태스크 목록을 작성해 보겠습니다. 다시 말해, 전형적인 "할 일" 목록 예제를 만들 것입니다. 이 프로젝트의 완성된 소스코드는 [https://github.com/laravel/quickstart-basic GitHub에서 확인]할 수 있습니다. |
|
| |
|
| ==설치== | | ==설치== |
| [[Laravel Homestead|Homestead 가상머신]]을 사용하거나 선택한 로컬 PHP 환경을 사용하여 프레임워크를 실행할 수 있습니다. 여기서는 도커 기반 실습환경에서 진행합니다.
| | ;Laravel 설치 |
| | 우선, Laravel 프레임워크을 새로 설치해야 합니다. Homestead 가상머신을 사용하거나 선택한 로컬 PHP 환경을 사용하여 프레임워크를 실행할 수 있습니다. 로컬 환경이 준비되면 Composer를 사용하여 Laravel 프레임워크를 설치할 수 있습니다: |
|
| |
|
| ===도커 기반 실습환경 (선택사항)===
| |
| <syntaxhighlight lang='bash'> | | <syntaxhighlight lang='bash'> |
| mkdir ~/workspace
| | composer create-project laravel/laravel quickstart --prefer-dist |
| cd ~/workspace
| |
| docker run --name laravel --rm -it -v ${PWD}:/workspace -w /workspace --network host -h docker --entrypoint="" bitnami/laravel bash
| |
| </syntaxhighlight>
| |
| <syntaxhighlight lang='console'>
| |
| root@wsl:~# mkdir ~/workspace
| |
| root@wsl:~# cd ~/workspace
| |
| root@wsl:~/workspace$ docker run --name laravel --rm -it -v ${PWD}:/workspace -w /workspace --network host -h docker --entrypoint="" bitnami/laravel bash
| |
| Unable to find image 'bitnami/laravel:latest' locally
| |
| latest: Pulling from bitnami/laravel
| |
| 3b20dd80ae86: Pull complete
| |
| Digest: sha256:d16af27a0d4c2f6f3f71c730d7def97de91e0b2ea0233e84dc758340521b1629
| |
| Status: Downloaded newer image for bitnami/laravel:latest
| |
| root@docker:/workspace#
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| ===Laravel 설치===
| | ;<del>Quickstart 설치 (선택사항)</del> |
| 환경이 준비되면 Composer를 사용하여 Laravel 프레임워크를 설치할 수 있습니다:
| | 나머지 Quickstart를 읽기만 해도 되지만, 소스코드를 다운로드하여 로컬 머신에서 실행하려면 Git 저장소를 복제하고 의존성을 설치할 수 있습니다: |
|
| |
|
| <syntaxhighlight lang='bash'> | | <syntaxhighlight lang='bash'> |
| composer create-project laravel/laravel quickstart --prefer-dist
| | git clone https://github.com/laravel/quickstart-basic quickstart |
| </syntaxhighlight>
| | cd quickstart |
| | | composer install |
| <syntaxhighlight lang='console'>
| | php artisan migrate |
| root@docker:/workspace# composer create-project laravel/laravel quickstart --prefer-dist
| |
| Creating a "laravel/laravel" project at "./quickstart"
| |
| Installing laravel/laravel (v11.1.1)
| |
| ...
| |
| INFO Preparing database.
| |
| | |
| Creating migration table ................................................... 7.50ms DONE
| |
| | |
| INFO Running migrations.
| |
| | |
| 0001_01_01_000000_create_users_table ...................................... 25.95ms DONE
| |
| 0001_01_01_000001_create_cache_table ....................................... 8.63ms DONE
| |
| 0001_01_01_000002_create_jobs_table ....................................... 21.42ms DONE
| |
| </syntaxhighlight>
| |
| <syntaxhighlight lang='console'>
| |
| root@docker:/workspace# cd quickstart/
| |
| root@docker:/workspace/quickstart# find app/ routes/ resources/ | grep .php
| |
| app/Providers/AppServiceProvider.php
| |
| app/Http/Controllers/Controller.php
| |
| app/Models/User.php
| |
| routes/console.php
| |
| routes/web.php
| |
| resources/views/welcome.blade.php
| |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| {{소스헤더|개발서버 실행}}
| | 로컬 Laravel 개발 환경 구축에 대한 보다 완전한 문서를 보려면, [[Laravel Homestead|Homestead]] 및 [[Laravel 설치|설치]] 문서를 참조하세요. |
| <syntaxhighlight lang='console'>
| |
| root@docker:/workspace/quickstart# php artisan serve
| |
| | |
| INFO Server running on [http://127.0.0.1:8000].
| |
| | |
| Press Ctrl+C to stop the server
| |
| | |
| ^C
| |
| </syntaxhighlight>
| |
| | |
| '''참고''': [[composer create-project laravel/laravel quickstart --prefer-dist]]
| |
| | |
| [[파일:Fresh-dark.png|640px]] | |
| | |
| ===vscode 실행 (선택사항)===
| |
| <syntaxhighlight lang='console'>
| |
| root@wsl:~# code ~/workspace/quickstart/
| |
| root@wsl:~#
| |
| </syntaxhighlight>
| |
| | |
| wsl에서는 docker와 디렉토리를 공유합니다. 따라서 vscode에서 파일 편집은 가능하지만 Artisan CLI 명령어는 실행할 수 없습니다. Artisan CLI 명령어는 docker 컨테이너 내부에서 실행해야 합니다.
| |
|
| |
|
| ==데이터베이스 준비== | | ==데이터베이스 준비== |
| ===데이터베이스 마이그레이션=== | | ===데이터베이스 마이그레이션=== |
| 먼저, 데이터베이스 테이블을 정의하기 위해 마이그레이션을 사용해 보겠습니다. Laravel의 데이터베이스 마이그레이션은 유창하고 표현적인 PHP 코드를 사용하여 데이터베이스 테이블 구조와 수정 사항을 쉽게 정의할 수 있는 방법을 제공합니다. 팀원들에게 데이터베이스의 로컬 복사본에 수동으로 열을 추가하라고 지시하는 대신, 소스 컨트롤에 푸시한 마이그레이션을 실행하기만 하면 됩니다. | | 먼저, 데이터베이스 마이그레이션을 사용하여 모든 태스크를 저장할 데이터베이스 테이블을 정의해보겠습니다. Laravel의 데이터베이스 마이그레이션은 유창하고 표현력 있는 PHP 코드를 사용하여 데이터베이스 테이블 구조 및 수정사항을 쉽게 정의할 수 있는 방법을 제공합니다. 팀원들에게 로컬 데이터베이스 복사본에 수동으로 컬럼을 추가하도록 지시하는 대신, 소스 컨트롤에 푸시한 마이그레이션을 실행하기만 하면 됩니다. |
|
| |
|
| 모든 태스크를 저장할 데이터베이스 테이블을 만들어봅시다. [[Artisan CLI]]를 사용하면 다양한 클래스를 생성할 수 있으며, Laravel 프로젝트를 구축하는 동안 많은 타이핑을 줄일 수 있습니다. 이번에는 <code>make:migration</code> 명령어를 사용하여 태스크 테이블에 대한 새 데이터베이스 마이그레이션을 생성해보겠습니다: | | 따라서 모든 태스크를 저장할 데이터베이스 테이블을 만들어봅시다. Artisan CLI를 사용하면 다양한 클래스를 생성할 수 있으며, Laravel 프로젝트를 구축하는 동안 많은 타이핑을 줄일 수 있습니다. 이번에는 <code>make:migration</code> 명령어를 사용하여 태스크 테이블에 대한 새 데이터베이스 마이그레이션을 생성해보겠습니다: |
|
| |
|
| <syntaxhighlight lang='bash'> | | <syntaxhighlight lang='bash'> |
| php artisan make:migration create_tasks_table --create=tasks | | php artisan make:migration create_tasks_table --create=tasks |
| </syntaxhighlight> | | </syntaxhighlight> |
| <syntaxhighlight lang='console'>
| |
| $ php artisan make:migration create_tasks_table --create=tasks
| |
|
| |
|
| INFO Migration [database/migrations/2024_06_15_101234_create_tasks_table.php] created successfully.
| | 마이그레이션 파일은 프로젝트의 <code>database/migrations</code> 디렉토리에 생성됩니다. 아마도 <code>make:migration</code> 명령어가 이미 자동 증가 ID와 타임스탬프를 마이그레이션 파일에 추가한 것을 보셨을 것입니다. 이 파일을 편집하여 작업 이름을 위한 추가 문자열 컬럼을 추가해봅시다: |
| </syntaxhighlight> | |
|
| |
|
| 마이그레이션 파일은 프로젝트의 <code>database/migrations</code> 디렉토리에 생성됩니다. 아마도 <code>make:migration</code> 명령어가 이미 자동 증가 ID와 타임스탬프를 마이그레이션 파일에 추가한 것을 보셨을 것입니다. 이 파일을 편집하여 작업 이름을 위한 <code>name</code> 문자열 컬럼을 추가해봅시다:
| | <syntaxhighlight lang='php'> |
| | |
| {{소스헤더|database/migrations/2024_06_15_101234_create_tasks_table.php}}
| |
| <syntaxhighlight lang='php' highlight='16'> | |
| <?php | | <?php |
|
| |
|
| | use Illuminate\Database\Schema\Blueprint; |
| use Illuminate\Database\Migrations\Migration; | | use Illuminate\Database\Migrations\Migration; |
| use Illuminate\Database\Schema\Blueprint;
| |
| use Illuminate\Support\Facades\Schema;
| |
|
| |
|
| return new class extends Migration
| | class CreateTasksTable extends Migration |
| { | | { |
| /** | | /** |
| * Run the migrations. | | * 마이그레이션을 실행합니다. |
| | * |
| | * @return void |
| */ | | */ |
| public function up(): void | | public function up() |
| { | | { |
| Schema::create('tasks', function (Blueprint $table) { | | Schema::create('tasks', function (Blueprint $table) { |
| $table->id(); | | $table->increments('id'); |
| $table->string('name'); | | $table->string('name'); |
| $table->timestamps(); | | $table->timestamps(); |
127번째 줄: |
65번째 줄: |
|
| |
|
| /** | | /** |
| * Reverse the migrations. | | * 마이그레이션을 되돌립니다. |
| | * |
| | * @return void |
| */ | | */ |
| public function down(): void | | public function down() |
| { | | { |
| Schema::dropIfExists('tasks'); | | Schema::drop('tasks'); |
| } | | } |
| }; | | } |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| 마이그레이션을 실행하려면 <code>migrate</code> Artisan 명령어를 사용합니다. Homestead를 사용 중이라면, 호스트 머신이 데이터베이스에 직접 접근할 수 없으므로, 가상머신 내에서 이 명령어를 실행해야 합니다: | | 마이그레이션을 실행하려면 <code>migrate</code> Artisan 명령어를 사용합니다. Homestead를 사용 중이라면, 호스트 머신이 데이터베이스에 직접 접근할 수 없으므로 가상머신 내에서 이 명령어를 실행해야 합니다: |
|
| |
|
| <syntaxhighlight lang='bash'> | | <syntaxhighlight lang='bash'> |
| php artisan migrate | | php artisan migrate |
| </syntaxhighlight> | | </syntaxhighlight> |
| <syntaxhighlight lang='console'>
| |
| $ php artisan migrate
| |
|
| |
| INFO Running migrations.
| |
|
| |
|
| 2024_06_15_101234_create_tasks_table ....................................... 9.24ms DONE
| | 이 명령어는 모든 데이터베이스 테이블을 생성합니다. 사용 중인 데이터베이스 클라이언트를 통해 데이터베이스 테이블을 확인하면, 마이그레이션에서 정의한 컬럼이 포함된 새로운 <code>tasks</code> 테이블을 볼 수 있을 것입니다. 다음으로, 작업에 대한 Eloquent ORM 모델을 정의할 준비가 되었습니다! |
| </syntaxhighlight>
| |
| | |
| 이 명령어는 모든 데이터베이스 테이블을 생성합니다. 사용 중인 데이터베이스 클라이언트를 통해 데이터베이스 테이블을 확인하면, 마이그레이션에서 정의한 컬럼이 포함된 새로운 <code>tasks</code> 테이블을 볼 수 있을 것입니다. 이제 Eloquent ORM 모델을 정의할 준비가 되었습니다! | |
|
| |
|
| ===Eloquent 모델=== | | ===Eloquent 모델=== |
| [[Laravel Eloquent|Eloquent]]는 Laravel의 기본 ORM(객체 관계 매퍼)입니다. Eloquent를 사용하면 명확하게 정의된 "모델"을 통해 데이터베이스에서 데이터를 쉽게 검색하고 저장할 수 있습니다. 일반적으로 각 Eloquent 모델은 단일 데이터베이스 테이블과 직접적으로 대응됩니다. | | [[Laravel Eloquent|Eloquent]]는 Laravel의 기본 ORM(객체 관계 매퍼)입니다. Eloquent를 사용하면 명확하게 정의된 "모델"을 사용하여 데이터베이스에서 데이터를 쉽게 검색하고 저장할 수 있습니다. 일반적으로 각 Eloquent 모델은 단일 데이터베이스 테이블과 직접적으로 대응됩니다. |
|
| |
|
| 따라서, 방금 생성한 <code>tasks</code> 데이터베이스 테이블에 대응되는 <code>Task</code> 모델을 정의해 봅시다. 이 경우, Artisan 명령어를 사용하여 이 모델을 생성할 수 있습니다. <code>make:model</code> 명령어를 사용할 것입니다: | | 따라서, 방금 생성한 <code>tasks</code> 데이터베이스 테이블에 대응되는 <code>Task</code> 모델을 정의해 봅시다. 이 경우, Artisan 명령어를 사용하여 이 모델을 생성할 수 있습니다. <code>make:model</code> 명령어를 사용할 것입니다: |
159번째 줄: |
92번째 줄: |
| php artisan make:model Task | | php artisan make:model Task |
| </syntaxhighlight> | | </syntaxhighlight> |
| <syntaxhighlight lang='console'>
| |
| $ php artisan make:model Task
| |
|
| |
| INFO Model [app/Models/Task.php] created successfully.
| |
| </syntaxhighlight>
| |
|
| |
|
| |
|
| 모델은 애플리케이션의 <code>app/Models</code> 디렉토리에 배치됩니다. 기본적으로 모델 클래스는 비어 있습니다. Eloquent 모델에 어떤 테이블과 대응되는지 명시적으로 알릴 필요는 없습니다. 왜냐하면 Eloquent는 모델 이름의 복수형을 데이터베이스 테이블로 가정하기 때문입니다. 따라서, <code>Task</code> 모델은 <code>tasks</code> 데이터베이스 테이블과 대응되는 것으로 간주됩니다. 빈 모델은 다음과 같이 생겼습니다: | | 모델은 애플리케이션의 <code>app</code> 디렉토리에 배치됩니다. 기본적으로 모델 클래스는 비어 있습니다. Eloquent 모델에 어떤 테이블과 대응되는지 명시적으로 알릴 필요는 없습니다. 왜냐하면 Eloquent는 모델 이름의 복수형을 데이터베이스 테이블로 가정하기 때문입니다. 따라서, <code>Task</code> 모델은 <code>tasks</code> 데이터베이스 테이블과 대응되는 것으로 간주됩니다. 빈 모델은 다음과 같이 생겼습니다: |
|
| |
|
| {{소스헤더|app/Models/Task.php}}
| |
| <syntaxhighlight lang='php'> | | <syntaxhighlight lang='php'> |
| <?php | | <?php |
| | | |
| namespace App\Models; | | namespace App; |
| | | |
| use Illuminate\Database\Eloquent\Factories\HasFactory;
| |
| use Illuminate\Database\Eloquent\Model; | | use Illuminate\Database\Eloquent\Model; |
| | | |
| class Task extends Model | | class Task extends Model |
| { | | { |
| use HasFactory; | | // |
| } | | } |
| </syntaxhighlight> | | </syntaxhighlight> |
|
| |
|
| 라우트를 애플리케이션에 추가하면서 Eloquent 모델을 사용하는 방법에 대해 더 알아볼 것입니다. 물론, 더 많은 정보를 원한다면 [[Eloquent: 시작하기|전체 Eloquent 문서]]를 참조해도 좋습니다. | | 라우트를 애플리케이션에 추가하면서 Eloquent 모델을 사용하는 방법에 대해 더 배워볼 것입니다. 물론, 더 많은 정보를 원한다면 [[Eloquent: 시작하기|전체 Eloquent 문서]]를 참조해도 좋습니다. |
|
| |
|
| ==라우팅== | | ==라우팅== |
| ===라우트 스터빙=== | | ===라우트 스터빙=== |
| 다음으로, 애플리케이션에 몇 가지 라우트를 추가할 준비가 되었습니다. 라우트는 URL을 컨트롤러나 사용자가 특정 페이지에 액세스할 때 실행해야 하는 익명 함수로 연결하는 데 사용됩니다. 기본적으로 모든 Laravel 라우트는 새로운 프로젝트에 포함된 <code>routes</code> 디렉토리에 정의됩니다. | | 다음으로, 애플리케이션에 몇 가지 라우트를 추가할 준비가 되었습니다. 라우트는 URL을 컨트롤러나 사용자가 특정 페이지에 액세스할 때 실행해야 하는 익명 함수로 연결하는 데 사용됩니다. 기본적으로 모든 Laravel 라우트는 새로운 프로젝트에 포함된 <code>app/Http/routes.php</code> 파일에 정의됩니다. |
|
| |
|
| 이 애플리케이션에서는 최소한 세 개의 라우트가 필요하다는 것을 알고 있습니다. 모든 태스크 목록을 표시하는 라우트, 새로운 태스크를 추가하는 라우트, 기존 태스크를 삭제하는 라우트가 필요합니다. 따라서, <code>routes/web.php</code> 파일에 이러한 모든 라우트를 스터빙해 보겠습니다: | | 이 애플리케이션에서는 최소한 세 개의 라우트가 필요하다는 것을 알고 있습니다. 모든 태스크 목록을 표시하는 라우트, 새로운 태스크를 추가하는 라우트, 기존 태스크를 삭제하는 라우트가 필요합니다. 따라서, <code>app/Http/routes.php</code> 파일에 이러한 모든 라우트를 스터빙해 보겠습니다: |
|
| |
|
| {{소스헤더|routes/web.php}}
| |
| <syntaxhighlight lang='php'> | | <syntaxhighlight lang='php'> |
| <?php | | <?php |
|
| |
|
| use Illuminate\Support\Facades\Route; | | use App\Task; |
| | use Illuminate\Http\Request; |
|
| |
|
| /** | | /** |
| * Show Task Dashboard | | * 작업 대시보드 표시 |
| */ | | */ |
| Route::get('/', function () { | | Route::get('/', function () { |
205번째 줄: |
130번째 줄: |
|
| |
|
| /** | | /** |
| * Add New Task | | * 새 작업 추가 |
| */ | | */ |
| Route::post('/task', function (Request $request) { | | Route::post('/task', function (Request $request) { |
212번째 줄: |
137번째 줄: |
|
| |
|
| /** | | /** |
| * Delete Task | | * 작업 삭제 |
| */ | | */ |
| Route::delete('/task/{task}', function (Task $task) { | | Route::delete('/task/{task}', function (Task $task) { |
218번째 줄: |
143번째 줄: |
| }); | | }); |
| </syntaxhighlight> | | </syntaxhighlight> |
| | |
| | {{NOTE}} |
| | 만약 여러분의 Laravel 버전에 이미 기본 라우트 파일을 <code>web</code> 미들웨어 그룹 내에 포함하는 <code>RouteServiceProvider</code>가 있다면, <code>routes.php</code> 파일에 그룹을 수동으로 추가할 필요가 없습니다. |
| | {{/NOTE}} |
|
| |
|
| ===뷰 표시하기=== | | ===뷰 표시하기=== |
| 다음으로, 우리의 <code>/</code> 라우트를 채워봅시다. 이 라우트에서는 새로운 작업을 추가하는 폼과 현재 모든 작업 목록을 포함하는 HTML 템플릿을 렌더링하고자 합니다. | | 다음으로, 우리의 / 라우트를 채워봅시다. 이 라우트에서는 새로운 작업을 추가하는 폼과 현재 모든 작업 목록을 포함하는 HTML 템플릿을 렌더링하고자 합니다. |
|
| |
|
| Laravel에서는 모든 HTML 템플릿이 <code>resources/views</code> 디렉토리에 저장되며, <code>view</code> 헬퍼를 사용하여 해당 라우트에서 이 템플릿 중 하나를 반환할 수 있습니다: | | Laravel에서는 모든 HTML 템플릿이 <code>resources/views</code> 디렉토리에 저장되며, <code>view</code> 헬퍼를 사용하여 해당 라우트에서 이 템플릿 중 하나를 반환할 수 있습니다: |
|
| |
|
| {{소스헤더|routes/web.php}}
| | <syntaxhighlight lang='php'> |
| <syntaxhighlight lang='php' highlight='2'> | |
| Route::get('/', function () { | | Route::get('/', function () { |
| return view('tasks'); | | return view('tasks'); |
234번째 줄: |
162번째 줄: |
|
| |
|
| ==레이아웃 및 뷰 구성== | | ==레이아웃 및 뷰 구성== |
| 이 애플리케이션에는 새 태스크을 추가하는 양식과 현재 모든 태스크를 목록을 포함하는 단일 뷰만 있습니다. 이 뷰를 시각적으로 이해할 수 있도록, 기본 Bootstrap CSS 스타일이 적용된 완성된 애플리케이션의 스크린샷을 여기에 첨부합니다.
| | ===레이아웃 정의=== |
| | | ===자식 뷰 정의=== |
| [[파일:basic-overview.png]]
| |
| | |
| ===레이아웃 정의하기=== | |
| 거의 모든 웹 애플리케이션은 페이지마다 동일한 레이아웃을 공유합니다. 예를 들어, 이 애플리케이션에는 모든 페이지에 공통으로 존재하는 상단 탐색 바가 있습니다. (만약 페이지가 둘 이상이라면) Laravel은 Blade '''레이아웃'''을 사용하여 이러한 공통 기능을 각 페이지에 쉽게 공유할 수 있도록 합니다.
| |
| | |
| 앞서 논의한 것처럼, 모든 Laravel 뷰는 <code>resources/views</code>에 저장됩니다. 따라서 <code>resources/views/layouts/app.blade.php</code>에 새로운 레이아웃 뷰를 정의해보겠습니다. <code>.blade.php</code> 확장자는 프레임워크에 [[Blade 템플릿 엔진]]을 사용하여 뷰를 렌더링하도록 지시합니다. 물론 Laravel에서 일반 PHP 템플릿을 사용할 수도 있습니다. 그러나 Blade는 깔끔하고 간결한 템플릿 작성을 위한 편리한 단축키를 제공합니다.
| |
| | |
| 우리의 <code>app.blade.php</code> 뷰는 다음과 같이 생겼습니다:
| |
| | |
| {{소스헤더|resources/views/layouts/app.blade.php}}
| |
| <syntaxhighlight lang='php'>
| |
| <!DOCTYPE html>
| |
| <html lang="en">
| |
| <head>
| |
| <title>Laravel Quickstart - Basic</title>
| |
| <link rel="stylesheet" href="https://unpkg.com/bootstrap@5/dist/css/bootstrap.min.css">
| |
| </head>
| |
| | |
| <body>
| |
| <nav class="navbar navbar-light bg-light border-bottom">
| |
| <div class="container-fluid">
| |
| Task List
| |
| </div>
| |
| </nav>
| |
| | |
| @yield('content')
| |
| </body>
| |
| </html>
| |
| </syntaxhighlight>
| |
| | |
| 이 레이아웃의 <code>@yield('content')</code> 부분을 주목하세요. 이는 자식 페이지가 레이아웃을 확장하여 자신의 콘텐츠를 주입할 수 있는 특별한 Blade 지시어입니다. 다음으로, 이 레이아웃을 사용할 자식 뷰를 정의하고 주요 콘텐츠를 제공해보겠습니다.
| |
| | |
| ===자식 뷰 정의하기=== | |
| 다음으로, 새 태스크를 생성하는 폼과 기존 작업을 나열하는 테이블을 포함하는 뷰를 정의해야 합니다. 이 뷰는 <code>resources/views/tasks.blade.php</code>에 정의할 것입니다.
| |
| | |
| Bootstrap CSS 보일러플레이트 일부는 생략하고 중요한 부분만 다루겠습니다. 이 애플리케이션의 전체 소스코드는 [https://github.com/laravel/quickstart-basic GitHub]에서 다운로드할 수 있습니다:
| |
| | |
| {{소스헤더|resources/views/tasks.blade.php}}
| |
| <syntaxhighlight lang='php'>
| |
| @extends('layouts.app')
| |
| | |
| @section('content')
| |
| | |
| <!-- Bootstrap Boilerplate... -->
| |
| <div class="card m-3">
| |
| <div class="card-header">
| |
| New Task
| |
| </div>
| |
| | |
| <div class="card-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="mb-3">
| |
| <label for="task">Task</label>
| |
| <input type="text" name="name" id="task" class="form-control">
| |
| </div>
| |
| | |
| <!-- Add Task Button -->
| |
| <button type="submit" class="btn btn-primary">
| |
| Add Task
| |
| </button>
| |
| </form>
| |
| </div>
| |
| </div>
| |
| | |
| <!-- TODO: Current Tasks -->
| |
| @endsection
| |
| </syntaxhighlight>
| |
| | |
| ;설명
| |
| 이 템플릿에 대해 조금 더 설명하겠습니다. 먼저, <code>@extends</code> 지시어는 Blade에게 우리가 <code>resources/views/layouts/app.blade.php</code>에 정의한 레이아웃을 사용하고 있음을 알립니다. <code>@section('content')</code>와 <code>@endsection</code> 사이의 모든 내용은 <code>app.blade.php</code> 레이아웃의 <code>@yield('content')</code> 지시어 위치에 삽입됩니다.
| |
| | |
| <code>@include('common.errors')</code> 지시어는 <code>resources/views/common/errors.blade.php</code>에 위치한 템플릿을 로드합니다. 이 템플릿은 아직 정의하지 않았지만, 곧 정의할 것입니다!
| |
| | |
| 이제 애플리케이션에 대한 기본 레이아웃과 뷰를 정의했습니다. 우리는 이 뷰를 <code>/</code> 라우트에서 다음과 같이 반환하고 있습니다:
| |
| | |
| {{소스헤더|routes/web.php}}
| |
| <syntaxhighlight lang='php'>
| |
| Route::get('/', function () {
| |
| return view('tasks');
| |
| });
| |
| </syntaxhighlight>
| |
| | |
| 다음으로, 폼 입력을 처리하고 데이터베이스에 새 작업을 추가하기 위한 <code>POST /task</code> 라우트에 코드를 추가할 준비가 되었습니다.
| |
| | |
| ==태스크 추가== | | ==태스크 추가== |
| ===유효성 검증=== | | ===유효성 검사=== |
| 이제 뷰에 폼을 만들었으니, <code>routes/web.php</code>의 <code>POST /task</code> 라우트에 코드를 추가하여 들어오는 폼 입력을 유효성 검증하고 새 태스크를 생성해야 합니다. 먼저, 입력을 검증해 봅시다.
| |
| | |
| 이 폼의 경우, <code>name</code> 필드를 필수로 하고, <code>255</code>자 이하로 제한할 것입니다. 검증에 실패하면 사용자를 <code>/</code> URL로 리디렉션하고, 이전 입력과 오류를 [[Laravel 세션|세션]]에 플래시할 것입니다. 입력을 세션에 플래시하면 검증 오류가 있을 때에도 사용자의 입력을 유지할 수 있습니다:
| |
| | |
| {{소스헤더|routes/web.php}}
| |
| <syntaxhighlight lang='php'>
| |
| Route::post('/task', function () {
| |
| $validator = Validator::make(Request::all(), [
| |
| 'name' => 'required|max:255',
| |
| ]);
| |
|
| |
| if ($validator->fails()) {
| |
| return redirect('/')
| |
| ->withInput()
| |
| ->withErrors($validator);
| |
| }
| |
|
| |
| // Create The Task...
| |
| });
| |
| </syntaxhighlight>
| |
| | |
| ;<code>$errors</code> 변수
| |
| 잠시 멈추고, 이 예제에서 <code>->withErrors($validator)</code> 부분에 대해 이야기해 봅시다. <code>->withErrors($validator)</code> 호출은 주어진 검증 인스턴스에서 오류를 세션에 플래시하여 뷰에서 <code>$errors</code> 변수를 통해 접근할 수 있도록 합니다.
| |
| | |
| 뷰에서 <code>@include('common.errors')</code> 지시어를 사용하여 폼의 검증 오류를 렌더링했던 것을 기억하십시오. <code>common.errors</code>는 모든 페이지에서 동일한 형식으로 검증 오류를 쉽게 보여줄 수 있게 합니다. 이제 이 뷰의 내용을 정의해 봅시다:
| |
| | |
| {{소스헤더|resources/views/common/errors.blade.php}}
| |
| <syntaxhighlight lang='php'>
| |
| @if (count($errors) > 0)
| |
| <!-- Form Error List -->
| |
| <div class="alert alert-danger">
| |
| <strong>Whoops! Something went wrong!</strong>
| |
|
| |
| <br><br>
| |
|
| |
| <ul>
| |
| @foreach ($errors->all() as $error)
| |
| <li>{{ $error }}</li>
| |
| @endforeach
| |
| </ul>
| |
| </div>
| |
| @endif
| |
| </syntaxhighlight>
| |
| | |
| '''참고''': <code>$errors</code> 변수는 '''모든''' Laravel 뷰에서 사용가능합니다. 검증 오류가 없는 경우, 단순히 빈 <code>ViewErrorBag</code> 인스턴스일 뿐입니다.
| |
| | |
| ===태스크 생성=== | | ===태스크 생성=== |
| 입력 검증이 처리되었으므로, 실제로 새 태스크를 생성하여 라우트를 계속 채워 나갑시다. 새 태스크가 생성되면 사용자를 <code>/</code> URL로 리디렉션합니다. 태스크를 생성하기 위해, 새로운 Eloquent 모델에 속성을 설정한 후 <code>save</code> 메소드를 사용할 수 있습니다:
| | ===기존 태스크 표시=== |
| | |
| {{소스헤더|routes/web.php}}
| |
| <syntaxhighlight lang='php' highlight='12-16'>
| |
| Route::post('/task', function () {
| |
| $validator = Validator::make(Request::all(), [
| |
| 'name' => 'required|max:255',
| |
| ]);
| |
|
| |
| if ($validator->fails()) {
| |
| return redirect('/')
| |
| ->withInput()
| |
| ->withErrors($validator);
| |
| }
| |
|
| |
| $task = new Task;
| |
| $task->name = Request::input('name');
| |
| $task->save();
| |
|
| |
| return redirect('/');
| |
| });
| |
| </syntaxhighlight>
| |
| | |
| 훌륭합니다! 이제 태스크를 성공적으로 생성할 수 있습니다. 다음으로, 모든 기존 태스크 목록을 작성하여 뷰를 계속 추가해 봅시다.
| |
| | |
| ===기존 태스크 표시하기=== | |
| 먼저, <code>/</code> 라우트를 수정하여 모든 기존 태스크를 뷰에 전달해야 합니다. <code>view</code> 함수는 배열 형태의 두 번째 인수를 받아들여 뷰에서 사용할 수 있는 데이터를 전달하며, 배열의 각 키는 뷰 내에서 변수가 됩니다:
| |
| | |
| {{소스헤더|routes/web.php}}
| |
| <syntaxhighlight lang='php' highlight='3,10-14'>
| |
| <?php
| |
| | |
| use App\Models\Task;
| |
| use Illuminate\Support\Facades\Route;
| |
| | |
| /**
| |
| * Show Task Dashboard
| |
| */
| |
| Route::get('/', function () {
| |
| $tasks = Task::orderBy('created_at', 'asc')->get();
| |
| | |
| return view('tasks', [
| |
| 'tasks' => $tasks
| |
| ]);
| |
| });
| |
| </syntaxhighlight>
| |
| | |
| 데이터가 전달되면, <code>tasks.blade.php</code> 뷰에서 태스크를 순회하여 테이블에 태스크를 표시할 수 있습니다. <code>@foreach</code> Blade 구조는 간결한 루프를 작성할 수 있게 해주며, 이는 빠른 순수 PHP 코드로 컴파일됩니다:
| |
| | |
| {{소스헤더|resources/views/tasks.blade.php}}
| |
| <syntaxhighlight lang='php'>
| |
| @extends('layouts.app')
| |
|
| |
| @section('content')
| |
| <!-- Create Task Form... -->
| |
|
| |
| <!-- Current Tasks -->
| |
| @if (count($tasks) > 0)
| |
| <div class="card m-3">
| |
| <div class="card-header">
| |
| Current Tasks
| |
| </div>
| |
|
| |
| <div class="card-body">
| |
| <table class="table table-striped">
| |
|
| |
| <!-- Table Headings -->
| |
| <thead>
| |
| <th>Task</th>
| |
| <th> </th>
| |
| </thead>
| |
|
| |
| <!-- Table Body -->
| |
| <tbody>
| |
| @foreach ($tasks as $task)
| |
| <tr>
| |
| <!-- Task Name -->
| |
| <td class="table-text">
| |
| <div>{{ $task->name }}</div>
| |
| </td>
| |
|
| |
| <td>
| |
| <!-- TODO: Delete Button -->
| |
| </td>
| |
| </tr>
| |
| @endforeach
| |
| </tbody>
| |
| </table>
| |
| </div>
| |
| </div>
| |
| @endif
| |
| @endsection
| |
| </syntaxhighlight>
| |
| | |
| 태스크 애플리케이션이 거의 완성되었습니다. 하지만, 완료된 작업을 삭제할 방법이 없습니다. 다음으로 삭제 기능을 추가해 보겠습니다!
| |
| | |
| ==태스크 삭제== | | ==태스크 삭제== |
| ===삭제 버튼 추가=== | | ===삭제 버튼 추가=== |
| 삭제 버튼을 추가해야 할 곳에 "TODO" 메모를 남겼습니다. 이제 <code>tasks.blade.php</code> 뷰의 태스크 목록 각 행에 삭제 버튼을 추가하겠습니다. 각 태스크에 대해 단일 버튼 폼을 생성할 것입니다. 버튼을 클릭하면 애플리케이션에 <code>DELETE /task</code> 요청이 전송됩니다.
| | ===태스크 삭제=== |
| | |
| {{소스헤더|resources/views/tasks.blade.php}}
| |
| <syntaxhighlight lang='php' highlight='7-17'>
| |
| <tr>
| |
| <!-- Task Name -->
| |
| <td>
| |
| {{ $task->name }}
| |
| </td>
| |
| | |
| <!-- Delete Button -->
| |
| <td>
| |
| <form action="{{ url('task/'.$task->id) }}" method="POST">
| |
| {{ csrf_field() }}
| |
| {{ method_field('DELETE') }}
| |
|
| |
| <button type="submit" class="btn btn-danger">
| |
| Delete
| |
| </button>
| |
| </form>
| |
| </td>
| |
| </tr>
| |
| </syntaxhighlight>
| |
| | |
| ;메소드 스푸핑에 대한 참고사항
| |
| HTML 폼은 <code>GET</code>과 <code>POST</code> HTTP 메소드만 허용하기 때문에, 폼 메소드가 <code>POST</code>로 나열되어 있지만, <code>DELETE</code> 요청을 처리하려면 <code>Route::delete</code> 라우트를 사용합니다. 폼에서 <code>DELETE</code> 요청을 스푸핑할 방법이 필요합니다.
| |
| | |
| 폼 에서 <code>method_field('DELETE')</code> 함수를 사용하여 <code>DELETE</code> 요청을 스푸핑할 수 있습니다. 이 함수는 Laravel이 인식하고 실제 HTTP 요청 메소드를 덮어쓸 숨겨진 폼 입력을 생성합니다. 생성되는 필드는 다음과 같습니다:
| |
| | |
| <syntaxhighlight lang='html'>
| |
| <input type="hidden" name="_method" value="DELETE">
| |
| </syntaxhighlight>
| |
| | |
| ===해당 태스크 삭제===
| |
| 마지막으로 주어진 태스크를 실제로 삭제하는 로직을 라우트에 추가하겠습니다. [[Laravel 라우팅#라우트 모델 바인딩|암시적 모델 바인딩]]을 사용하여 <code>{task}</code> 라우트 파라미터에 해당하는 <code>Task</code> 모델을 자동으로 조회할 수 있습니다.
| |
| | |
| 라우트 콜백에서는, <code>delete</code> 메소드를 사용하여 레코드를 삭제합니다. 레코드가 삭제되면 사용자를 <code>/</code> URL로 리디렉션합니다:
| |
| | |
| {{소스헤더|routes/web.php}}
| |
| <syntaxhighlight lang='php'>
| |
| Route::delete('/task/{task}', function (Task $task) {
| |
| $task->delete();
| |
|
| |
| return redirect('/');
| |
| });
| |
| </syntaxhighlight>
| |