초보자를 위한 라라벨 튜토리얼

⚡ 스마트 요약

Laravel은 Taylor Otwell이 웹 애플리케이션을 빠르고 깔끔하게 구축하기 위해 만든 오픈 소스 PHP MVC 프레임워크입니다. 이 튜토리얼에서는 Laravel이 무엇인지, Composer를 사용하여 설치하는 방법, 그리고 라우트, 컨트롤러, 폼 요청 유효성 검사 및 Blade 템플릿을 사용하여 작동하는 파일 업로드 앱을 구축하는 방법을 설명합니다.

  • 🎂 Laravel이란 무엇인가: Laravel은 패키지 관리자, 데이터베이스 도구 및 표현력이 풍부한 구문을 갖춘 최신 PHP MVC 프레임워크로, 빠른 개발에 적합합니다.
  • 📦 Composer 설치: Composer는 Laravel을 설치하고, `laravel new` 명령어는 전체 디렉토리 구조를 갖춘 새로운 애플리케이션을 생성합니다.
  • 🧭 경로 : routes/web.php 파일의 경로는 URI와 HTTP 동사를 컨트롤러 메서드에 매핑하며, 기억하기 쉬운 이름을 지정할 수 있습니다.
  • 🎛️ 컨트롤러 : 컨트롤러는 요청을 수신하고 응답을 반환합니다.ping 액션 로직은 경로 정의와 분리되어 있습니다.
  • ✅ 양식 요청: 폼 요청 클래스는 유효성 검사 규칙을 가지고 있으므로, 유효하지 않은 데이터는 컨트롤러에 도달하기 전에 거부됩니다.
  • 🖼️ 블레이드 템플릿: Blade는 @csrf 및 route()와 같은 지시문을 사용하여 HTML을 렌더링하며, 여기서는 비동기 업로드를 위해 jQuery와 함께 사용됩니다.
  • 🤖 AI 지원: AI 도구는 Laravel CRUD 앱의 기본 구조를 만들고 기존 프로젝트를 최신 Laravel 버전으로 업그레이드하는 데 도움을 줄 수 있습니다.

라라벨 튜토리얼

라라벨이란?

Laravel PHP용 오픈 소스 웹 MVC 프레임워크입니다. Laravel은 전용 종속성 관리자가 포함된 모듈식 패키징 시스템, 관계형 데이터베이스에 대한 액세스, 애플리케이션 배포 및 유지 관리를 위한 기타 유틸리티와 같은 기능을 통해 PHP 웹 애플리케이션을 쉽게 개발할 수 있는 강력한 프레임워크입니다.

Laravel은 Taylor Otwell이 개발했습니다. 2011년 6월 첫 출시(버전 1) 이후 웹 개발 업계의 PHP 프레임워크 분야에서 꾸준히 인기를 얻어 왔습니다. 이러한 인기의 상당 부분은 개발자 중심적인 기능들이 기본적으로 많이 탑재되어 있다는 점에 기인합니다.

왜 라라벨인가?

2000년경 대부분 PHP 코드 절차적이며 스파게티 코드가 엉켜있는 "스크립트" 형태로 발견될 수 있습니다. 가장 단순한 페이지에도 우려의 분리그래서 애플리케이션이 금세 유지보수하기 어려운 악몽으로 변하는 것은 매우 쉬운 일이었습니다. 세상에는 더 나은 무언가가 필요했습니다. PHP 5 버전과 다양한 PHP 프레임워크가 등장하여 웹 애플리케이션의 여러 문제에 필요한 구조와 더 나은 해결책을 제시하고자 했습니다.

그 이후로 오늘날 널리 사용되는 프레임워크의 토대를 마련한 수많은 프레임워크가 출시되었습니다. 현재 저희 생각에 최고의 프레임워크 세 가지는 Zend Framework, Symfony, 그리고 Laravel입니다. 이 프레임워크들은 모두 비슷한 원칙에 기반을 두고 있으며 (기본적으로) 동일한 공통 문제를 해결하는 것을 목표로 하지만, 구현 방식에서 핵심적인 차이점이 있습니다. 각 프레임워크는 문제를 해결하는 방식에 있어 고유한 특징을 가지고 있습니다. 각 프레임워크로 작성된 코드를 살펴보면 서로 확연히 구분되는 것을 알 수 있습니다. 저희의 개인적인 의견으로는 Laravel 프레임워크가 최고입니다.

더 많은 내용을 확인하세요. Laravel과 Code이그나이터.

Composer로 Laravel을 다운로드하고 설치하는 방법

참고 : 이 튜토리얼은 Laravel 5.8을 기준으로 작성되었지만, 라우팅, 컨트롤러, 요청 및 Blade 개념은 현재 릴리스에서도 동일하게 적용됩니다. 2026년 기준 최신 버전은 Laravel 13(2026년 3월 출시)이며, PHP 8.3 이상이 필요합니다. 반면 Laravel 12는 PHP 8.2가 필요합니다.

참고 : 이 설명서에서는 사용자의 로컬 시스템에 PHP가 이미 설치되어 있다고 가정합니다. 만약 설치되어 있지 않다면, PHP 설치 방법을 참조하십시오. 여기에서 확인하세요.

Composer는 패키지이자 종속성 관리자입니다. 설치하려면 터미널을 열고 새 디렉토리로 cd를 실행합니다. 다음 명령을 실행합니다.

curl -Ss getcomposer.org/installer | php

이 명령의 결과는 다음과 같습니다.

Composer로 Laravel 다운로드 및 설치

참고 : Laravel 설정에 대한 자세한 내용은 Laravel 문서를 참조하십시오. 여기에서 확인하세요.

그러면 Laravel을 설치하는 데 사용되는 composer.phar 스크립트가 다운로드되고 컴파일되는 것을 볼 수 있습니다. 새로운 Laravel 애플리케이션을 설정하는 방법은 여러 가지가 있지만, 여기서는 Laravel composer 스크립트를 이용하겠습니다. 이 스크립트를 설치하려면 다음 명령을 실행하세요.

composer global require laravel/installer

다음과 같이 보일 것입니다:

Composer로 Laravel 다운로드 및 설치

이렇게 하면 프레임워크 파일 자체와 필요한 모든 종속성이 다운로드 및 설치됩니다. 패키지는 vendor 디렉터리에 저장됩니다. 다운로드 및 설치가 완료되면 다음 명령만 실행하면 됩니다.

laravel new uploadApp

다음과 같은 출력이 표시됩니다.

Composer로 Laravel 다운로드 및 설치

Composer가 Laravel 실행에 필요한 모든 패키지를 설치하고 있습니다. 몇 분 정도 소요될 수 있으니 잠시 기다려 주세요. 설치가 완료되면 `ls -al` 명령어를 실행하여 설치된 패키지를 확인하세요.

다음은 일반적인 Laravel 애플리케이션의 디렉터리에 대한 간략한 설명입니다:

  • 앱/ : 이 폴더는 애플리케이션 코드가 저장되는 소스 폴더입니다. 모든 컨트롤러, 정책 및 모델은 이 폴더 안에 있습니다.
  • 부트스트랩/ : 이 폴더에는 애플리케이션의 시작 스크립트와 몇 개의 클래스 맵 파일이 들어 있습니다.
  • 구성/ : 앱의 설정 파일을 저장합니다. 이러한 파일은 일반적으로 직접 수정되지 않고, 앱 루트에 있는 .env(환경) 파일에 설정된 값을 사용합니다.
  • 데이터베이스/ : 마이그레이션, 시드, 테스트 팩토리 등을 포함한 데이터베이스 파일이 저장됩니다.
  • 공공의/ : 컴파일된 에셋과 index.php 파일이 들어 있는 공개적으로 접근 가능한 폴더입니다.
  • 자원/ : 프런트엔드 자산을 포함합니다. Java스크립트 파일, 언어 파일, CSS/SASS 파일, 그리고 애플리케이션에서 사용되는 모든 템플릿(블레이드 템플릿이라고 함)이 포함됩니다.
  • 경로/ : 애플리케이션의 모든 경로는 이 파일 안에 있습니다. 경로에는 몇 가지 다른 "범위"가 있지만, 우리가 집중할 경로는 web.php 파일입니다.
  • 저장/ : 응용 프로그램에서 사용하는 모든 임시 캐시 파일, 세션 파일, 컴파일된 뷰 스크립트 및 로그 파일.
  • 테스트/ : 이 폴더에는 단위 테스트 및 기능 테스트와 같은 애플리케이션 테스트 파일이 포함되어 있습니다.
  • 공급업체/ : Composer를 사용하여 모든 종속 패키지를 설치했습니다.

자, 이제 나머지 앱 빌드를 진행하고 특별한 artisan 명령어를 사용하여 실행해 보겠습니다(Apache나 nginx 같은 웹 서버를 설치하고 구성하는 번거로움을 덜기 위해서입니다). .env 파일에는 /config 디렉터리의 파일들이 애플리케이션을 구성하는 데 사용하는 모든 설정 값이 포함되어 있습니다.

애플리케이션 설계: 요구 사항에 대한 빠른 요약

이 온라인 Laravel 튜토리얼에서 우리는 다음 두 가지 작업만 수행하는 매우 간단한 애플리케이션을 구축할 것입니다:

  1. 웹 양식에서 파일 업로드 처리
  2. 이전에 업로드한 파일을 다른 페이지에 표시합니다.

이 프로젝트에서 우리가 만들 애플리케이션은 쓰기 전용입니다. 즉, 사용자는 파일을 작성하고 자신이 업로드한 파일 목록을 보는 것만 가능합니다. 이 애플리케이션은 매우 기본적인 기능만 제공하지만, 여러분이 Laravel 기술과 지식을 쌓기 시작하는 데 좋은 연습이 될 것입니다. 간결성을 위해 데이터베이스 모델링, 마이그레이션, 인증은 제외했지만, 실제 애플리케이션에서는 이러한 요소들도 고려해야 합니다.

다음은 애플리케이션이 예상대로 작동하도록 하기 위해 필요한 구성 요소 목록입니다.

  • A 길 이는 외부 세계(인터넷)에서 애플리케이션을 사용할 수 있도록 허용하는 동시에 업로드된 파일을 저장하는 로직이 위치한 엔드포인트를 지정합니다.
  • A 제어 장치 요청과 응답 사이의 흐름을 처리하는 부분입니다.
  • A 이 템플릿 이는 이전에 업로드된 파일 목록과 실제 업로드 양식을 표시하는 데 사용될 것입니다.
  • A 의뢰 컨트롤러가 웹 폼에서 전달된 데이터를 검증하는 데 사용할 값입니다.

경로란 무엇입니까?

Laravel에서 라우트는 기본적으로 애플리케이션이 제공하는 특정 기능에 대한 "포인터" 역할을 하는 URI로 지정된 엔드포인트입니다. 가장 흔하게는 라우트가 컨트롤러의 메서드를 가리키며, 해당 URI에 접근할 수 있는 HTTP 메서드를 지정합니다. 라우트는 항상 컨트롤러 메서드를 의미하는 것은 아니며, 정의된 클로저나 익명 함수로 애플리케이션 실행을 전달하는 역할도 할 수 있습니다.

경로를 사용하는 이유는 무엇인가요?

경로는 프로젝트 루트 디렉토리 내의 /routes 폴더 아래에 있는 파일에 저장됩니다. 기본적으로 애플리케이션의 다른 "측면"에 해당하는 몇 가지 다른 파일이 있습니다("측면"은 육각형 아키텍처 방법론에서 유래). 여기에는 다음이 포함됩니다.

  • web.php: 브라우저 기반의 공개 경로입니다. 가장 일반적이며 웹 브라우저가 접근하는 경로입니다. 웹 미들웨어 그룹을 통해 실행되며 다음과 같은 기능도 포함합니다. CSRF 보호 (이는 폼 기반 악성 공격으로부터 방어하는 데 도움이 되며) 일반적으로 어느 정도의 "상태"를 포함합니다(여기서 상태란 세션을 활용한다는 의미입니다).
  • api.php: API 그룹에 해당하는 경로이며, 따라서 API 미들웨어가 기본적으로 활성화되어 있습니다. 이러한 경로는 상태를 저장하지 않으며 세션이나 요청 간 메모리 공유가 없습니다(각 요청은 다른 요청과 데이터나 메모리를 공유하지 않으며, 자체적으로 캡슐화됩니다).
  • console.php: 이러한 경로는 앱을 위해 생성한 사용자 지정 Artisan 명령에 해당합니다.
  • channels.php: 이벤트 방송을 위한 경로를 등록합니다.

이 시점에서 가장 중요한 파일은 브라우저별 파일인 web.php입니다. 기본적으로 하나의 경로가 이미 정의되어 있는데, 이는 애플리케이션의 웹 루트(public 디렉터리에 있음)로 이동했을 때 바로 연결되는 경로입니다. 업로드 애플리케이션이 제대로 작동하려면 세 가지 다른 경로가 필요합니다.

  • /upload: 이 주소는 파일 업로드를 위한 웹 양식이 표시되는 메인 페이지의 URI입니다.
  • /process: 이 주소는 /upload URI에 있는 폼이 제출한 데이터를 전송하는 위치(폼의 "액션")입니다.
  • /list: 이 명령어를 사용하면 사이트에 업로드된 모든 파일 목록이 표시됩니다.

참고 : 업로드 양식과 파일 목록을 표시하는 모든 로직을 단일 페이지에 넣으려는 경우 /list 엔드포인트는 필요하지 않을 수 있습니다. 하지만 현재로서는 주제에 좀 더 깊이를 더하기 위해 두 기능을 분리해 두었습니다.

//inside routes/web.php
Route::get('/upload', 'UploadController@upload')->name('upload');
Route::get('/download', 'UploadController@download')->name('download');
Route::post('/process', 'UploadController@process')->name('process');
Route::get('/list', 'UploadController@list')->name('list');

이 Laravel 프레임워크 튜토리얼에서는 원하는 각 경로를 `web.php` 파일의 `routes` 파일에 명시적으로 나열하고, 사용 가능한 HTTP 요청 메서드(`get()`, `post()`, `put()`, `delete()`, `patch()`, 또는 `options()`) 중 하나를 사용합니다. 각 메서드에 대한 자세한 설명은 다음을 참조하세요. 이 `Route::any()` 메서드는 특정 경로에 접근할 수 있는 HTTP 동사를 지정하는 역할을 합니다. 경로가 여러 HTTP 동사를 허용해야 하는 경우(예: 단일 페이지에서 초기 데이터를 표시하고 제출된 폼 데이터를 전송하는 경우)에는 `Route::any()` 메서드를 사용할 수 있습니다.

Route::get() 및 Route::post() 메서드(그리고 Route 파사드의 다른 모든 HTTP 동사 관련 메서드)의 두 번째 인수는 특정 컨트롤러의 이름과 해당 컨트롤러 내부에 있는 메서드입니다. 이 메서드는 허용된 HTTP 요청(GET, POST, PATCH 등)으로 해당 경로의 엔드포인트에 도달했을 때 실행됩니다. 우리는 모든 경로에 UploadController를 사용하고 있으며 다음과 같이 지정했습니다.

경로란 무엇입니까?

각 경로에서 마지막으로 호출하는 메서드는 `name()` 함수입니다. 이 함수는 단일 문자열을 인수로 받아 특정 경로에 기억하기 쉬운 이름(저희의 경우 `upload`, `process`, `list`)을 지정하는 데 사용됩니다. 각 경로에 고유한 이름을 부여하는 것이 그다지 훌륭한 기능처럼 보이지 않을 수도 있습니다. URL 이름은 완전히 똑같지만, /users/profile/dashboard/config처럼 특정 경로가 있을 때 profile-admin이나 user-config처럼 기억하기 쉬운 이름으로 바꾸는 것이 훨씬 편리합니다.

파사드에 대한 참고 사항:

  • 파사드는 애플리케이션의 서비스 컨테이너에서 사용할 수 있는 클래스에 대한 "정적" 인터페이스를 제공합니다.
  • 수동으로 삽입하거나 구성해야 하는 긴 클래스 이름을 기억하지 않고도 Laravel의 기능을 사용할 수 있도록 간결하고 기억에 남는 구문을 제공합니다.

위의 경로 정의에서는 Illuminate/Routing/Router 객체를 수동으로 생성하고 해당 객체의 메서드를 호출하는 대신 Route 파사드를 사용했습니다. 이는 단순히 시간을 절약하기 위한 간편한 방법입니다.ping라라벨 프레임워크 전반에 걸쳐 파사드가 많이 사용되므로, 파사드에 익숙해지는 것이 좋습니다. 파사드 관련 문서는 다음에서 확인할 수 있습니다. 여기에서 확인하세요.

컨트롤러란 무엇입니까?

컨트롤러는 Laravel이 기반을 둔 "MVC"(모델-뷰-컨트롤러) 아키텍처의 "C"입니다. 컨트롤러의 작업은 이 간단한 정의로 요약할 수 있습니다. 클라이언트로부터 요청을 받아 클라이언트에게 응답을 반환합니다. 이것은 가장 기본적인 정의이며, 모든 컨트롤러의 최소 요구 사항이기도 합니다. 이 두 가지 사이에서 컨트롤러가 수행하는 작업은 일반적으로 컨트롤러의 "액션"(또는 "라우트 구현")으로 간주됩니다. 컨트롤러는 클라이언트가 애플리케이션에 접근하는 두 번째 진입점(첫 번째는 요청) 역할을 하며, 클라이언트는 요청 페이로드(다음에서 자세히 설명)를 애플리케이션으로 전송하고, 성공 페이지, 리디렉션, 오류 페이지 또는 기타 HTTP 응답 형태의 응답을 기대합니다.

컨트롤러는 (기본적으로) 라우트 정의와 동일한 기능을 수행하지만, 해당 라우트에 접근했을 때 실행될 "액션"으로 익명 함수가 설정됩니다. 차이점은 컨트롤러는 관심사 분리 원칙을 잘 준수하는 반면, 라우트는 실제 코드에 직접 정의된다는 점입니다. URL 정의는 기본적으로 경로에 할당된 URI와 경로 구현, 즉 해당 경로에 접근했을 때 실행되는 코드를 연결하는 것을 의미합니다.

예를 들어, 다음 두 코드는 동일한 결과를 달성합니다.

예제 #1: 단일 메서드 호출 내에서 경로 정의 및 구현(web.php 경로 파일)

//inside routes/web.php
<?php
Route::get('/hello-world', function(Request $request) {
$name = $request->name;
return response()->make("<h1>Hello World! This is ".$name, 200);
});

예시 #2: 경로 정의는 routes/web.php 파일 안에 있지만, 구현은 /app/Http/Controllers/HelloWorldController 클래스 안에 있습니다.

//inside routes/web.php
<?php

Route::get('/hello-world', 'HelloWorldController@index')->name('hello-world');

------------------------------------------------------------------------------------
//inside app/Http/Controllers/HelloWorldController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class HelloWorldController extends Controller
{
public function index(Request $request)
{
$name = $request->name;
return response()->make("<h1>Hello World! This is ".$name, 200);
}
}

Laravel 예제 #2가 훨씬 더 많은 작업량처럼 보이지만(실제로는 코드가 조금 더 많을 뿐입니다), "hello-world" 경로에 대한 액션 로직을 콜백 함수로 정의하는 대신 컨트롤러 안에 넣음으로써 얻는 이점을 살펴보세요.

  1. 우리의 로직은 별도의 클래스로 깔끔하게 분리되어 있습니다(관심사 분리).
  2. 저희 컨트롤러는 나중에 필요에 따라 추가 기능을 확장할 수 있도록 설계되었습니다. 예를 들어 "안녕히 가세요" 기능을 추가하고 싶다고 가정해 보겠습니다. 이 경우 컨트롤러 이름을 "HelloController"와 같이 더 일반적인 이름으로 변경한 다음, 두 개의 별도 메서드를 정의하면 됩니다. 안녕하세요() 안녕히 가세요(). 또한 다음을 매핑하는 두 개의 별도 경로를 정의해야 합니다. /안녕하세요 / 안녕 컨트롤러의 해당 메서드에 대한 URI를 제공합니다. 이는 각 경로의 구현을 콜백 함수로 정의하여 경로 파일을 복잡하게 만드는 것보다 바람직합니다.
  3. Laravel에는 애플리케이션의 모든 경로 정의를 캐시하는 기능이 내장되어 있어 주어진 경로를 찾는 데 걸리는 시간을 단축합니다(애플리케이션 성능 향상). 그러나 애플리케이션 내의 모든 정의된 경로가 컨트롤러별 맵을 사용하여 구성된 경우에만 해당 기능을 활용할 수 있습니다.ping(위의 예시 #2 참조).

새로운 컨트롤러를 생성하는 다음 명령어를 실행해 보겠습니다.

// ...inside the project's root directory:
php artisan make:controller UploadController

기본적으로 이 명령어는 메인 컨트롤러 디렉터리인 /app/Http/Controllers/UploadController.php에 "UploadController"라는 이름의 컨트롤러 스텁을 생성합니다. 해당 파일을 열어서 살펴보셔도 좋습니다. 네임스페이스 경로와 상속받는 클래스만 포함된, 컨트롤러의 스텁 버전이기 때문에 매우 간단합니다.

요청 생성

이 PHP Laravel 튜토리얼을 진행하면서 UploadController의 생성된 스텁을 수정하기 전에, 먼저 request 클래스를 생성하는 것이 좋습니다. 요청을 처리하는 컨트롤러 메서드는 메서드 시그니처에 request 객체를 타입 힌트로 명시해야 하기 때문입니다. 이를 통해 들어오는 폼 데이터를 자동으로 검증할 수 있습니다(rules() 메서드에 명시된 대로, 자세한 내용은 나중에 설명). 이제 artisan 명령어를 다시 사용하여 request 스텁을 생성해 보겠습니다.

php artisan make:request UploadFileRequest

이 명령은 app/Http/Requests/UploadFileRequest 경로에 UploadFileRequest라는 파일을 생성합니다. 해당 스텁 파일을 열어 내용을 살펴보세요. authorize()와 rules()라는 두 가지 메서드만 포함된 매우 간단한 파일임을 알 수 있을 것입니다.

검증 로직 생성

우리 애플리케이션의 요구 사항에 맞게 요청 스텁을 수정해 보겠습니다. 파일을 다음과 같이 수정하세요.

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UploadFileRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}

/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'fileName' => 'required|string',
'userFile' => 'required|file'
];
}
}

크게 달라진 점은 없지만, authorize() 메서드가 이제 false 대신 true를 반환한다는 점에 주목하세요. 이 메서드는 요청이 애플리케이션으로 들어갈 수 있는지 여부를 결정합니다. false로 설정하면 요청이 시스템에 들어가지 못하게 됩니다. 사용자 권한 확인이나 요청이 컨트롤러로 진행될 수 있는지 여부를 결정하는 다른 로직을 여기에 넣으면 매우 유용할 것입니다. 현재는 모든 요청을 허용하기 위해 true를 반환합니다.

다른 메서드인 rules()는 유효성 검사와 관련된 모든 핵심 기능을 담당하는 부분입니다. 아이디어는 간단합니다. 다음과 같은 형식의 규칙 집합을 담은 배열을 반환합니다.

'formFieldName' => 'constraints this field has separated by pipe characters (|)'

Laravel에서 바로 지원하는 다양한 검증 제약 조건이 있습니다. 전체 목록은 온라인 설명서를 확인하세요. 여기에서 확인하세요파일 업로드 애플리케이션에서는 프런트엔드의 폼에서 POST 요청을 통해 두 개의 필드를 전달받습니다. `fileName` 매개변수는 폼 본문에 반드시 포함되어야 하며(필수), 스토리지에 파일을 저장할 파일 이름으로 사용됩니다(이 작업은 컨트롤러에서 처리되며, 나중에 자세히 설명하겠습니다). 또한 파일 이름은 문자열이어야 하므로 파이프 문자(|)와 'string'을 추가하여 지정합니다. 제약 조건은 항상 파이프 문자로 구분되므로 한 줄에 해당 필드에 대한 추가 조건을 지정할 수 있습니다.

두 번째 매개변수인 userFile은 사용자가 웹페이지의 양식을 통해 업로드하는 실제 파일입니다. userFile 또한 필수 매개변수입니다. 절대로 필요한 것 파일이 되십시오. 참고 : 업로드할 파일이 이미지일 것으로 예상했다면, 파일 형식을 일반적인 이미지 형식(jpeg, png, bmp, gif, svg)으로 제한하는 이미지 제약 조건을 사용했을 것입니다. 하지만 사용자가 어떤 형식의 파일이든 업로드할 수 있도록 허용하려는 경우라면, 파일 유효성 검사 제약 조건을 그대로 사용하겠습니다.

요청 객체의 주요 역할은 폼 본문의 매개변수가 애플리케이션의 다음 단계로 진행하기 위해 충족해야 하는 허용 가능한 기준(제약 조건) 집합을 저장하는 것입니다. 또한, 이 두 필드(userFile 및 fileName)는 HTML 코드 내에서도 입력 필드 형태로 지정되어야 하며, 필드 이름은 요청 객체 내의 이름과 동일해야 합니다.

여러분은 이렇게 질문할 수도 있습니다. "이것은 양식 요청에 포함되어야 하는 내용의 특징을 정의하지만, 이러한 제약 조건에 대한 실제 검사는 어디에서 이루어지는 걸까요?" 다음으로 자세히 살펴보겠습니다.

컨트롤러 수정

앱/Http/Controllers/UploadController를 열고 다음과 같이 변경합니다.

<?php

namespace App\Http\Controllers;

use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Http\Request;
use App\Http\Requests\UploadFileRequest; //our new request class
use Illuminate\Support\Facades\Storage;

class UploadController extends Controller
{
/**
* This is the method that will simply list all the files uploaded by name and provide a
* link to each one so they may be downloaded
*
* @param $request : A standard form request object
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws BindingResolutionException
*/
public function list(Request $request)
{
$uploads = Storage::allFiles('uploads');

return view('list', ['files' => $uploads]);
}

/**
* @param $file
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
* @throws BindingResolutionException
*/
public function download($file)
{
return response()->download(storage_path('app/'.$file));
}

/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws BindingResolutionException
*/
public function upload()
{
return view('upload');
}

/**
* This method will handle the file uploads. Notice that the parameter's typehint
* is the exact request class we generated in the last step. There is a reason for this!
*
* @param $request : The special form request for our upload application
* @return array|\Illuminate\Http\UploadedFile|\Illuminate\Http\UploadedFile[]|null
* @throws BindingResolutionException
*/
public function process(UploadFileRequest $request)
{
//At this point, the parameters passed into the $request (from form) are
//valid--they satisfy each of the conditions inside the rules() method

$filename = $request->fileName; //parameters have already been validated
$file = $request->file('userFile'); //so we don't need any additional isset()

$extension = $file->getClientOriginalExtension(); //grab the file extension
$saveAs = $filename . "." . $extension; //filename to save file under

$file->storeAs('uploads', $saveAs, 'local'); //save the file to local folder

return response()->json(['success' => true]); //return a success message
}
}

따라서 업로드된 파일을 디스크에 저장하는 방법은 상당히 간단합니다. 위 process() 메서드에 대한 분석은 다음과 같습니다.

  • 주요 기능을 수행하는 컨트롤러 메서드에 요청 클래스를 타입 힌트로 지정하여 들어오는 데이터를 자동으로 검증할 수 있도록 합니다.
  • 컨트롤러 메서드 내부에서 (이제 유효성 검사를 마친) 요청 객체에서 파일을 가져옵니다.
  • 요청에서 파일 이름을 추출하세요.
  • 파일을 저장하는 데 사용할 최종 파일 이름을 생성합니다. getClientOriginalExtension() 메소드는 업로드된 파일의 원래 확장자를 가져옵니다.
  • storeAs() 메소드를 사용하여 파일을 로컬 파일 시스템에 저장하고 /storage 디렉토리 내부의 명명된 경로를 첫 번째 인수로 전달하고 파일 이름을 두 번째 인수로 전달합니다.
  • 요청이 성공했음을 나타내는 JSON 응답을 반환합니다.

블레이드 템플릿

이 퍼즐의 마지막 주요 조각은 모든 HTML, CSS 및 기타 코드를 담을 블레이드 템플릿입니다. Java간단한 애플리케이션용 스크립트입니다. 코드는 다음과 같으며, 나중에 설명하겠습니다.

<body>
<h1>Upload a file</h1>
<form id="uploadForm" name="uploadForm" action="{{route('process')}}" enctype="multipart/form-data">
@csrf
<label for="fileName">File Name:</label>
<input type="text" name="fileName" id="fileName" required /><br />
<label for="userFile">Select a File</label>
<input type="file" name="userFile" id="userFile" required />
<button type="submit" name="submit">Submit</button>
</form>
<h2 id="success" style="color:green;display:none">Successfully uploaded file</h2>
<h2 id="error" style="color:red;display:none">Error Submitting File</h2>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$('#uploadForm').on('submit', function(e) {
e.preventDefault();
var form = $(this);
var url = form.attr('action');
$.ajax({
url: url,
type: "POST",
data: new FormData(this),
processData: false,
contentType: false,
dataType: "JSON",
success: function(data) {
$("#fileName").val("");
$("#userFile").val("");
}
}).done(function() {
$('#success').css('display', 'block');
window.setTimeout(()=>($("#success").css('display', 'none')), 5000);
}).fail(function() {
$('#error').css('display', 'block');
window.setTimeout(()=>($("#error").css('display', 'none')), 5000);
});
});
</script>
</body>
</html>

여기에 우리의 /업로드 페이지는 다음과 같습니다:

블레이드 템플릿

이것은 HTML 폼을 포함하는 블레이드 파일의 매우 전형적인 예입니다. Java페이지가 새로 고쳐지지 않는 비동기 기능을 추가하기 위한 스크립트/jQuery 코드입니다. 기본적인 내용은 다음과 같습니다. 메서드 속성이 없는 태그(이에 대해서는 잠시 후에 설명하겠습니다)와 {{route('process')}}라는 특이한 액션 속성이 있습니다. Blade 템플릿 엔진에서는 이를 '프로세스'라고 부릅니다. 지침. 디렉티브는 함수를 가리키는 세련된 이름일 뿐입니다. 블레이드 템플릿에 특화된 함수로서 웹 페이지와 웹 애플리케이션을 구축하는 데 공통적으로 사용되는 다양한 작업을 수행합니다. 블레이드가 제공하는 유용한 기능들을 더 자세히 알아보려면 공식 문서를 참조하세요. 여기에서 확인하세요위의 경우, 우리는 경로 지시문을 사용하여 생성하고 있습니다. URL 양식 제출을 위해서입니다.

웹 애플리케이션의 웹 파일(web.php)에서 각 경로에 기억하기 쉬운 이름을 지정하여 경로를 정의했던 것을 기억하세요. {{route()}} 지시문은 경로 이름을 인수로 받아 내부적으로 캐시된 경로 목록에서 해당 경로를 찾아 전체 경로를 생성합니다. URL 웹.php 파일에 정의된 해당 경로에 따라 달라집니다. 첫 번째 경우에는 폼이 제출한 데이터를 /process 경로로 보내도록 지정합니다. URL 저희 애플리케이션은 다음과 같이 정의됩니다. POST 경로.

다음으로 눈치채셨을 만한 것은 폼 태그 바로 아래에 있는 `@csrf` 태그입니다. Blade 템플릿 엔진에서 이 태그는 폼에 `_token` 매개변수를 생성하며, 이 토큰은 폼 데이터 처리가 허용되기 전에 애플리케이션 내부에서 검사됩니다. 이는 폼에 입력된 데이터가 유효한 출처에서 온 것인지 확인하고 교차 사이트 요청 위조(CSRF) 공격을 방지합니다. 자세한 내용은 다음을 참조하세요. 문서.

이후에는 일반적인 방식으로 폼을 정의합니다. 다만, 폼 매개변수 이름인 userFile과 fileName은 각각 다르다는 점에 유의하십시오. 같은 정확한 요청 객체 내부에 정의된 대로입니다. 요청 객체에 정의된 특정 매개변수에 대한 입력을 누락했거나(또는 오타가 있는 경우) 요청이 실패하고 오류가 반환되어 원래 폼 요청이 UploadController@process에 있는 컨트롤러 메서드에 도달하지 못하게 됩니다.

한번 사용해 보시고, 이 양식을 사용하여 애플리케이션에 몇 가지 파일을 제출해 보세요. 그런 다음, 다음 페이지로 이동하세요. /목록 업로드한 파일이 표에 나열되어 있는 업로드 폴더의 내용을 보려면 다음 페이지를 참조하세요.

블레이드 템플릿

더 큰 그림

잠시 뒤로 물러나서 이번 라라벨 튜토리얼에서 우리가 무엇을 했는지 살펴보겠습니다.

이 다이어그램은 현재 애플리케이션의 현황을 보여줍니다(상위 수준 세부 정보는 제외).

Laravel 튜토리얼 다이어그램

이 Laravel 튜토리얼 초반에 생성한 request 객체의 rules 메서드에 정의된 매개변수가 Blade 템플릿의 폼에 정의된 매개변수와 동일해야 한다는 점을 기억하세요(만약 그렇지 않다면 "유효성 검사 로직 생성" 섹션을 다시 읽어보세요). 사용자는 Blade 템플릿 엔진을 통해 렌더링된 웹 페이지에서 폼을 입력하고 제출합니다. 템플릿 하단의 jQuery 코드는 기본 제출(자동으로 다른 페이지로 리디렉션되는 기능)을 중지하고, Ajax 요청을 생성하여 폼 데이터와 업로드된 파일을 요청에 로드한 다음, 전체 내용을 애플리케이션의 첫 번째 레이어인 request로 보냅니다.

요청 객체는 rules() 메서드 내의 매개변수와 제출된 폼 매개변수를 연결하여 채워지고, 지정된 각 규칙에 따라 데이터의 유효성을 검사합니다. 모든 규칙이 충족되면 요청은 web.php 경로 파일에 정의된 값에 해당하는 컨트롤러 메서드로 전달됩니다. 이 경우 UploadController의 process() 메서드가 해당 작업을 수행합니다. 컨트롤러에 도달하면 요청이 유효성 검사를 통과했음을 이미 알고 있으므로, 입력된 파일 이름이 문자열인지 또는 userFile 매개변수에 실제로 파일 형식이 포함되어 있는지 다시 검사할 필요가 없습니다. 따라서 평소처럼 계속 진행할 수 있습니다.

컨트롤러 메서드는 요청 객체에서 유효성 검사를 거친 매개변수를 가져와 전달된 fileName 매개변수에 userFile의 원래 확장자를 연결하여 전체 파일 이름을 생성하고, 해당 파일을 애플리케이션 내의 디렉터리에 저장한 다음, 요청이 성공했음을 확인하는 간단한 JSON 인코딩 응답을 반환합니다. 이 응답을 받은 jQuery 로직은 성공(또는 오류) 메시지를 5초 동안 표시한 후 숨기고 이전 폼 입력 내용을 지우는 등의 UI 관련 작업을 추가로 수행합니다. 이를 통해 사용자는 요청이 성공했음을 확실히 알 수 있으며, 원할 경우 다른 파일을 업로드할 수 있습니다.

또한 위 다이어그램에서 클라이언트와 서버를 구분하는 경계선을 잘 살펴보세요. 이 개념은 매우 중요하며, 예를 들어 여러 개의 비동기 요청이 동시에 발생할 때 발생할 수 있는 문제를 해결하는 데 큰 도움이 될 것입니다. 클라이언트와 서버는 요청 객체의 경계에서 분리됩니다. 요청 객체는 애플리케이션의 나머지 부분으로 들어가는 "관문" 역할을 합니다. 웹 브라우저에서 전달된 폼 값의 초기 유효성 검사 및 등록을 담당하며, 값이 유효하면 컨트롤러로 전달됩니다. 그 이전의 모든 작업은 프런트엔드("클라이언트"는 말 그대로 "사용자 컴퓨터"를 의미)에서 처리됩니다. 응답은 애플리케이션에서 클라이언트 측으로 반환되며, jQuery 코드는 응답을 기다렸다가 수신되면 몇 가지 간단한 UI 작업을 수행합니다.

또한 자주 묻는 중요한 질문들에 대해서도 많이 다뤘습니다. Laravel 및 PHP 관련 인터뷰 질문 신입뿐만 아니라 경력 지원자도 올바른 직업을 얻을 수 있습니다.

자주 묻는 질문

Eloquent는 Laravel의 내장 객체 관계형 매퍼입니다. 각 데이터베이스 테이블은 모델 클래스에 매핑되므로 일반적인 작업을 위해 원시 SQL을 작성하는 대신 User::find(1)와 같은 PHP 객체로 행을 읽고 쓸 수 있습니다.

Artisan은 Laravel의 명령줄 도구입니다. `make:controller` 및 `make:request`와 같은 명령어를 사용하여 코드를 스캐폴딩하고, 마이그레이션을 실행하고, 캐시를 지우고, `php artisan serve`로 로컬 서버를 시작하여 일반적인 개발 작업을 가속화합니다.

미들웨어는 HTTP 요청이 경로에 도달하기 전에 검사하거나 필터링하고, 나가는 응답을 처리합니다. 인증, CSRF 보호, 로깅과 같은 공통적인 문제들을 경로별 또는 그룹별로 처리합니다.

네. 모델과 필드를 설명해 주시면 AI가 Laravel 규칙에 따라 마이그레이션, Eloquent 모델, 컨트롤러, 폼 요청, 라우트 및 Blade 뷰를 생성할 수 있습니다. Rev배송 전에 유효성 검사 규칙을 확인하고 테스트를 실행하세요.ping.

네. AI는 더 이상 사용되지 않는 메서드, 변경된 구성 및 네임스페이스, 업데이트된 패키지 요구 사항을 식별하여 버전별 업그레이드를 안내할 수 있습니다. 업그레이드 범위가 넓으므로 단계적으로 업그레이드하고 각 단계 후에 테스트하십시오.

이 게시물을 요약하면 다음과 같습니다.