Laravel 유효성 검증

(Laravel validation에서 넘어옴)

1 개요[ | ]

Laravel Validation
라라벨 밸리데이션, 유효성 검증, 유효성 검사

https://laravel.com/docs/11.x/validation

Crystal Clear action info.png 작성 중인 문서입니다.


2 소개[ | ]

Laravel은 애플리케이션으로 들어오는 데이터를 검증하기 위해 여러 가지 접근 방식을 제공합니다. 가장 일반적으로는 모든 들어오는 HTTP 요청에서 사용할 수 있는 validate 메소드를 사용하는 방법이 있습니다. 그러나 여기서는 다른 검증 접근 방식들도 함께 논의할 것입니다.

Laravel은 데이터에 적용할 수 있는 다양한 편리한 검증 규칙을 포함하고 있으며, 특정 데이터베이스 테이블에서 값이 고유한지 검증할 수 있는 기능도 제공합니다. Laravel의 모든 검증 기능에 익숙해질 수 있도록 각 검증 규칙을 자세히 다룰 것입니다.

3 유효성 검증 빠른 시작[ | ]

Laravel의 강력한 유효성 검사 기능을 배우기 위해, 폼을 검증하고 사용자에게 오류 메시지를 표시하는 전체 예제를 살펴보겠습니다. 이 고수준 개요를 통해 Laravel을 사용하여 들어오는 요청 데이터를 검증하는 방법에 대한 좋은 일반적인 이해를 얻을 수 있을 것입니다:

3.1 라우트 정의[ | ]

먼저, routes/web.php 파일에 다음과 같은 라우트가 정의되어 있다고 가정해 보겠습니다:

use App\Http\Controllers\PostController;
 
Route::get('/post/create', [PostController::class, 'create']);
Route::post('/post', [PostController::class, 'store']);

GET 라우트는 사용자가 새로운 블로그 포스트를 작성할 수 있는 폼을 표시하고, POST 라우트는 새로운 블로그 포스트를 데이터베이스에 저장합니다.

3.2 컨트롤러 생성[ | ]

다음으로, 이러한 경로로 들어오는 요청을 처리하는 간단한 컨트롤러를 살펴보겠습니다. store 메소드는 아직 비워둡니다:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class PostController extends Controller
{
    /**
     * 새 블로그 게시물을 작성하는 폼을 보여줍니다.
     */
    public function create(): View
    {
        return view('post.create');
    }

    /**
     * 새 블로그 게시물을 저장합니다.
     */
    public function store(Request $request): RedirectResponse
    {
        // 블로그 게시물을 검증하고 저장합니다...

        $post = /** ... */

        return to_route('post.show', ['post' => $post->id]);
    }
}

3.3 유효성 검증 로직 작성[ | ]

이제 새 블로그 게시물을 유효성 검증할 로직을 store 메소드에 작성할 준비가 되었습니다. 이를 위해 Illuminate\Http\Request 객체에서 제공하는 validate 메소드를 사용할 것입니다. 유효성 검증 규칙을 통과하면 코드가 정상적으로 계속 실행됩니다. 그러나 유효성 검증이 실패하면 Illuminate\Validation\ValidationException 예외가 발생하고 사용자에게 적절한 오류 응답이 자동으로 반환됩니다.

전통적인 HTTP 요청 중 유효성 검증이 실패하면 이전 URL로 리디렉션 응답이 생성됩니다. 들어오는 요청이 XHR 요청인 경우 유효성 검증 오류 메시지를 포함한 JSON 응답이 반환됩니다.

validate 메소드를 더 잘 이해하기 위해 store 메소드로 돌아가 봅시다:

/**
 * 새로운 블로그 게시물 저장.
 */
public function store(Request $request): RedirectResponse
{
    $validated = $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    // 블로그 게시물 유효성 검증 통과...

    return redirect('/posts');
}

보다시피, 검증 규칙이 validate 메소드에 전달됩니다. 모든 사용 능한 검증 규칙은 문서화되어 있으니 걱정하지 마십시오. 검증에 실패하면 적절한 응답이 자동으로 생성됩니다. 검증에 성공하면 컨트롤러는 정상적으로 실행을 계속합니다.

또한 검증 규칙은 |로 구분된 문자열 대신 규칙 배열로 지정할 수 있습니다:

$validatedData = $request->validate([
    'title' => ['required', 'unique:posts', 'max:255'],
    'body' => ['required'],
]);


또한, validateWithBag 메소드를 사용하여 요청을 검증하고, 오류 메시지를 명명된 오류 백에 저장할 수 있습니다:

$validatedData = $request->validateWithBag('post', [
    'title' => ['required', 'unique:posts', 'max:255'],
    'body' => ['required'],
]);
첫 번째 유효성 검증 실패 시 중지하기

때로는 첫 번째 유효성 검증 실패 후 해당 속성에 대한 유효성 검증 규칙 실행을 중지하고 싶을 수 있습니다. 이를 위해 속성에 bail 규칙을 할당할 수 있습니다:

$request->validate([
    'title' => 'bail|required|unique:posts|max:255',
    'body' => 'required',
]);

이 예시에서, title 속성의 unique 규칙이 실패하면 max 규칙은 검증하지 않습니다. 규칙은 할당된 순서대로 유효성이 검증됩니다.

중첩된 속성에 관한 노트

만약 들어오는 HTTP 요청에 "중첩된" 필드 데이터가 포함되어 있다면, "점(dot)" 구문을 사용하여 이 필드들을 유효성 검증 규칙을 지정할 수 있습니다:

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'author.name' => 'required',
    'author.description' => 'required',
]);

반면에, 필드 이름에 실제 점(점 문자)이 포함된 경우에는, 백슬래시로 점을 이스케이프하여 "점(dot)" 구문으로 해석되는 것을 명시적으로 방지할 수 있습니다:

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'v1\.0' => 'required',
]);

3.4 유효성 검증 오류 표시[ | ]

그래서 들어오는 요청 필드가 주어진 유효성 검증 규칙을 통과하지 못하면 어떻게 될까요? 앞서 언급한 바와 같이, Laravel은 자동으로 사용자를 이전 위치로 리디렉션합니다. 또한, 모든 유효성 검증 오류와 요청 입력이 자동으로 세션에 플래시됩니다.

Illuminate\View\Middleware\ShareErrorsFromSession 미들웨어는 $errors 변수를 애플리케이션의 모든 뷰와 공유하는데, 이 미들웨어는 웹 미들웨어 그룹에 의해 제공됩니다. 이 미들웨어가 적용되면 $errors 변수는 항상 뷰에서 사용할 수 있으며, 이를 통해 $errors 변수가 항상 정의되어 안전하게 사용할 수 있다고 가정할 수 있습니다. $errors 변수는 Illuminate\Support\MessageBag의 인스턴스가 됩니다. 이 객체를 사용하는 방법에 대한 자세한 정보는 해당 문서를 참고하세요.

이 예제에서, 유효성 검증이 실패하면 사용자는 컨트롤러의 create 메소드로 리디렉션되어 뷰에서 오류 메시지를 표시할 수 있게 됩니다:

/resources/views/post/create.blade.php
<h1>Create Post</h1>

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<!-- 게시물 작성  -->
오류 메시지 커스터마이징

Laravel의 빌트인 유효성 검증 규칙 각각에는 애플리케이션의 lang/en/validation.php 파일에 위치한 오류 메시지가 있습니다. 애플리케이션에 lang 디렉토리가 없다면, lang:publish Artisan 명령어를 사용하여 Laravel에게 이를 생성하도록 지시할 수 있습니다.

lang/en/validation.php 파일 안에서는 각 유효성 검증 규칙에 대한 번역 항목을 찾을 수 있습니다. 애플리케이션의 필요에 따라 이 메시지들을 자유롭게 변경하거나 수정할 수 있습니다.

또한, 이 파일을 다른 언어 디렉토리로 복사하여 애플리케이션의 언어에 맞게 메시지를 번역할 수도 있습니다. Laravel 현지화에 대해 더 알고 싶다면, 전체 현지화 문서를 참고하세요.

Warning

기본적으로, Laravel 애플리케이션 스켈레톤에는 lang 디렉토리가 포함되어 있지 않습니다. Laravel의 언어 파일을 커스터마이징하려면, lang:publish Artisan 명령어를 통해 이를 게시할 수 있습니다.

XHR 요청 및 유효성 검증

이 예제에서는 전통적인 폼을 사용하여 데이터를 애플리케이션으로 전송했습니다. 그러나 많은 애플리케이션은 JavaScript 기반 프론트엔드에서 XHR 요청을 받습니다. XHR 요청 중에 validate 메소드를 사용할 때, Laravel은 리디렉션 응답을 생성하지 않습니다. 대신, Laravel은 모든 유효성 검증 오류를 포함하는 JSON 응답을 생성합니다. 이 JSON 응답은 422 HTTP 상태 코드와 함께 전송됩니다.

@error 지시어

@error Blade 지시어를 사용하여 주어진 속성에 대한 유효성 검증 오류 메시지가 존재하는지 빠르게 확인할 수 있습니다. @error 지시어 내에서 $message 변수를 출력하여 오류 메시지를 표시할 수 있습니다:

/resources/views/post/create.blade.php
<label for="title">Post Title</label>

<input id="title"
    type="text"
    name="title"
    class="@error('title') is-invalid @enderror">

@error('title')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror

명명된 오류 백을 사용하는 경우, @error 지시어의 두 번째 인수로 오류 백의 이름을 전달할 수 있습니다:

<input ... class="@error('title', 'post') is-invalid @enderror">

3.5 폼 다시 채우기[ | ]

Laravel이 유효성 검증 오류로 인해 리디렉션 응답을 생성할 때, 프레임워크는 자동으로 요청의 모든 입력을 세션에 플래시합니다. 이렇게 하면 다음 요청 시 입력을 편리하게 액세스하고 사용자가 제출하려고 했던 폼을 다시 채울 수 있습니다.

이전 요청에서 플래시된 입력을 검색하려면 Illuminate\Http\Request 인스턴스에서 old 메소드를 호출합니다. old 메소드는 세션에서 이전에 플래시된 입력 데이터를 가져옵니다:

$title = $request->old('title');

Laravel은 또한 글로벌 old 헬퍼를 제공합니다. 블레이드 템플릿 내에서 이전 입력을 표시하는 경우, old 헬퍼를 사용하여 폼을 다시 채우는 것이 더 편리합니다. 주어진 필드에 대한 이전 입력이 없는 경우 null이 반환됩니다:

<input type="text" name="title" value="{{ old('title') }}">

3.6 선택적 필드 참고사항[ | ]

기본적으로, Laravel은 TrimStringsConvertEmptyStringsToNull 미들웨어를 애플리케이션의 글로벌 미들웨어 스택에 포함시킵니다. 이로 인해, null 값을 유효하지 않은 것으로 간주하지 않도록 하려면 "선택적(optional)" 요청 필드를 nullable로 표시해야 할 때가 많습니다. 예를 들면 다음과 같습니다:

$request->validate([
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
    'publish_at' => 'nullable|date',
]);

이 예시에서는 publish_at 필드가 null이거나 유효한 날짜 표현일 수 있음을 명시하고 있습니다. 규칙 정의에 nullable 수정자를 추가하지 않으면, 유효성 검증기는 null을 유효하지 않은 날짜로 간주할 것입니다.

3.7 유효성 검증 오류 응답 형식[ | ]

애플리케이션에서 Illuminate\Validation\ValidationException 예외가 발생하고 들어오는 HTTP 요청이 JSON 응답을 예상하는 경우, Laravel은 자동으로 오류 메시지를 형식화하여 422 Unprocessable Entity HTTP 응답을 반환합니다.

아래에서는 유효성 검증 오류에 대한 JSON 응답 형식의 예시를 볼 수 있습니다. 중첩된 오류 키는 "점" 표기법 형식으로 평탄화된다는 점에 유의하세요.

{
    "message": "The team name must be a string. (and 4 more errors)",
    "errors": {
        "team_name": [
            "The team name must be a string.",
            "The team name must be at least 1 characters."
        ],
        "authorization.role": [
            "The selected authorization.role is invalid."
        ],
        "users.0.email": [
            "The users.0.email field is required."
        ],
        "users.2.email": [
            "The users.2.email must be a valid email address."
        ]
    }
}

4 폼 요청 유효성 검증[ | ]

4.1 폼 요청 생성[ | ]

더 복잡한 검증 시나리오에서는 "폼 요청"을 생성하고 싶을 수 있습니다. 폼 요청은 자체 검증 및 인가 로직을 캡슐화하는 커스텀 요청 클래스입니다. 폼 요청 클래스를 생성하려면 make:request Artisan CLI 명령어를 사용할 수 있습니다:

php artisan make:request StorePostRequest

생성된 폼 요청 클래스는 app/Http/Requests 디렉토리에 배치됩니다. 이 디렉토리가 존재하지 않으면 make:request 명령어를 실행할 때 생성됩니다. Laravel에서 생성된 각 폼 요청에는 authorizerules라는 두 가지 메소드가 있습니다.

authorize 메소드는 현재 인증된 사용자가 요청에서 나타내는 작업을 수행할 수 있는지를 결정하는 역할을 하며, rules 메소드는 요청 데이터에 적용할 검증 규칙을 반환합니다:

/**
 * 요청에 적용할 검증 규칙을 가져옵니다.
 *
 * @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
 */
public function rules(): array
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}

Note

rules 메소드의 시그니처에 필요한 모든 의존성을 타입 힌트할 수 있습니다. 이는 Laravel 서비스 컨테이너를 통해 자동으로 해결됩니다.

그렇다면 검증 규칙은 어떻게 평가될까요? 컨트롤러 메소드에서 요청을 타입 힌트하면 됩니다. 들어오는 폼 요청은 컨트롤러 메소드가 호출되기 전에 검증되므로 컨트롤러에 검증 로직을 추가할 필요가 없습니다:

/**
 * 새 블로그 게시물을 저장합니다.
 */
public function store(StorePostRequest $request): RedirectResponse
{
    // 들어오는 요청은 유효합니다...
 
    // 검증된 입력 데이터를 검색합니다...
    $validated = $request->validated();
 
    // 검증된 입력 데이터의 일부를 검색합니다...
    $validated = $request->safe()->only(['name', 'email']);
    $validated = $request->safe()->except(['name', 'email']);
 
    // 블로그 게시물을 저장합니다...
 
    return redirect('/posts');
}

검증이 실패하면 사용자를 이전 위치로 되돌리기 위해 리디렉션 응답이 생성됩니다. 오류는 세션에 플래시되어 표시할 수 있도록 제공됩니다. 요청이 XHR 요청인 경우, 검증 오류의 JSON 표현을 포함하는 422 상태 코드의 HTTP 응답이 사용자에게 반환됩니다.

Note

Inertia 기반 Laravel 프론트엔드에 실시간 폼 요청 검증을 추가하려고 하나요? Laravel Precognition을 확인해 보세요.

추가 유효성 검증 수행

초기 검증이 완료된 후 추가 검증이 필요할 때가 있습니다. 이를 위해 폼 요청의 after 메소드를 사용할 수 있습니다.

after 메소드는 검증이 완료된 후 호출될 콜러블 또는 클로저 배열을 반환해야 합니다. 지정된 콜러블은 Illuminate\Validation\Validator 인스턴스를 받아 필요 시 추가 오류 메시지를 발생시킬 수 있습니다:

use Illuminate\Validation\Validator;

/**
 * 요청에 대한 "after" 검증 콜러블을 가져옵니다.
 */
public function after(): array
{
    return [
        function (Validator $validator) {
            if ($this->somethingElseIsInvalid()) {
                $validator->errors()->add(
                    'field',
                    'Something is wrong with this field!'
                );
            }
        }
    ];
}

언급된 것처럼, after 메소드가 반환하는 배열에는 호출가능한(invokable) 클래스도 포함될 수 있습니다. 이러한 클래스의 __invoke 메소드는 Illuminate\Validation\Validator 인스턴스를 받게 됩니다:

use App\Validation\ValidateShippingTime;
use App\Validation\ValidateUserStatus;
use Illuminate\Validation\Validator;

/**
 * 요청에 대한 "after" 검증 콜러블을 가져옵니다.
 */
public function after(): array
{
    return [
        new ValidateUserStatus,
        new ValidateShippingTime,
        function (Validator $validator) {
            //
        }
    ];
}
첫 번째 검증 실패 시 중지

요청 클래스에 stopOnFirstFailure 속성을 추가하면 단일 검증 실패가 발생할 때 모든 속성 검증을 중지하도록 유효성 검증기에 알릴 수 있습니다:

/**
 * 유효성 검증기가 첫 번째 규칙 실패 시 중지해야 하는지 여부를 나타냅니다.
 *
 * @var bool
 */
protected $stopOnFirstFailure = true;
리디렉션 위치 커스터마이징

앞서 논의한 바와 같이, 폼 요청 검증이 실패할 때 사용자를 이전 위치로 되돌리기 위한 리디렉션 응답이 생성됩니다. 그러나 이 동작을 커스터마이징할 수 있습니다. 이를 위해 폼 요청에 $redirect 속성을 정의하세요:

/**
 * 검증 실패 시 사용자가 리디렉션되어야 하는 URI입니다.
 *
 * @var string
 */
protected $redirect = '/dashboard';

또는, 사용자를 명명된 라우트로 리디렉션하고 싶다면 $redirectRoute 속성을 정의할 수 있습니다:

/**
 * 검증 실패 시 사용자가 리디렉션되어야 하는 라우트입니다.
 *
 * @var string
 */
protected $redirectRoute = 'dashboard';

4.2 폼 요청 인가[ | ]

폼 요청 클래스에는 authorize 메소드도 포함되어 있습니다. 이 메소드 내에서 인증된 사용자가 실제로 특정 리소스를 업데이트할 권한이 있는지 확인할 수 있습니다. 예를 들어, 사용자가 업데이트하려고 하는 블로그 댓글을 실제로 소유하고 있는지 확인할 수 있습니다. 대부분의 경우, 이 메소드 내에서 인가 게이트와 정책을 사용하여 상호작용하게 될 것입니다:

use App\Models\Comment;
 
/**
 * 사용자가 이 요청을 수행할 권한이 있는지 확인합니다.
 */
public function authorize(): bool
{
    $comment = Comment::find($this->route('comment'));
 
    return $comment && $this->user()->can('update', $comment);
}

모든 폼 요청은 기본 Laravel 요청 클래스를 확장하므로, user 메소드를 사용하여 현재 인증된 사용자에 접근할 수 있습니다. 또한, 위 예제에서 route 메소드 호출에 주목하세요. 이 메소드는 호출 중인 라우트에 정의된 URI 파라미터에 접근할 수 있게 해줍니다. 예를 들어 아래 예제의 {comment} 파라미터에 접근할 수 있습니다:

Route::post('/comment/{comment}');

따라서, 애플리케이션이 라우트 모델 바인딩을 활용하고 있다면, 요청의 속성으로 해결된 모델에 접근하여 코드를 더욱 간결하게 만들 수 있습니다:

return $this->user()->can('update', $this->comment);

authorize 메소드가 false를 반환하면 HTTP 403 상태 코드가 자동으로 반환되고 컨트롤러 메소드는 실행되지 않습니다.

만약 요청의 인가 로직을 애플리케이션의 다른 부분에서 처리하려는 경우, authorize 메소드를 완전히 제거하거나 단순히 true를 반환할 수 있습니다:

/**
 * 사용자가 이 요청을 수행할 권한이 있는지 확인합니다.
 */
public function authorize(): bool
{
    return true;
}

Note

authorize 메소드의 시그니처 내에서 필요한 의존성을 타입 힌트로 지정할 수 있습니다. 이 의존성들은 Laravel 서비스 컨테이너를 통해 자동으로 해결됩니다.

4.3 오류 메시지 커스터마이징[ | ]

폼 요청에 사용되는 오류 메시지를 커스터마이징하려면 messages 메소드를 오버라이드하면 됩니다. 이 메소드는 속성 / 규칙 쌍과 해당하는 오류 메시지를 반환하는 배열을 리턴해야 합니다:

/**
 * 정의된 유효성 검증 규칙에 대한 오류 메시지를 가져옵니다.
 *
 * @return array<string, string>
 */
public function messages(): array
{
    return [
        'title.required' => 'A title is required',
        'body.required' => 'A message is required',
    ];
}
유효성 검증 속성 커스터마이징

Laravel의 많은 기본 유효성 검증 규칙 오류 메시지에는 :attribute 플레이스홀더가 포함되어 있습니다. 유효성 검사 메시지의 :attribute 플레이스홀더를 커스텀 속성 이름으로 교체하려면 attributes 메소드를 오버라이드하여 커스텀 이름을 지정할 수 있습니다. 이 메소드는 속성 / 이름 쌍의 배열을 반환해야 합니다:

/**
 * 유효성 검증 오류에 대한 커스텀 속성을 가져옵니다.
 *
 * @return array<string, string>
 */
public function attributes(): array
{
    return [
        'email' => 'email address',
    ];
}

4.4 유효성 검증 입력 준비[ | ]

검증 규칙을 적용하기 전에 요청에서 데이터를 준비하거나 위생처리해야 하는 경우, prepareForValidation 메소드를 사용할 수 있습니다:

use Illuminate\Support\Str;
 
/**
 * 유효성 검증을 위한 데이터를 준비합니다.
 */
protected function prepareForValidation(): void
{
    $this->merge([
        'slug' => Str::slug($this->slug),
    ]);
}

마찬가지로, 검증이 완료된 후 요청 데이터를 정규화해야 하는 경우, passedValidation 메소드를 사용할 수 있습니다:

/**
 * 유효성 검증 시도가 통과된 후 처리를 합니다.
 */
protected function passedValidation(): void
{
    $this->replace(['name' => 'Taylor']);
}

5 수동 유효성 검증기 생성[ | ]

요청에서 validate 메소드를 사용하지 않으려면, Validator 파사드를 사용하여 수동으로 Validator 인스턴스를 생성할 수 있습니다. 파사드의 make 메소드는 새로운 Validator 인스턴스를 생성합니다:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class PostController extends Controller
{
    /**
     * 새로운 블로그 포스트를 저장합니다.
     */
    public function store(Request $request): RedirectResponse
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ]);

        if ($validator->fails()) {
            return redirect('post/create')
                        ->withErrors($validator)
                        ->withInput();
        }

        // 유효성 검증된 입력값을 가져옵니다...
        $validated = $validator->validated();

        // 유효성 검증된 입력값의 일부를 가져옵니다...
        $validated = $validator->safe()->only(['name', 'email']);
        $validated = $validator->safe()->except(['name', 'email']);

        // 블로그 포스트를 저장합니다...

        return redirect('/posts');
    }
}

make 메소드에 전달되는 첫 번째 인수는 유효성 검증를 할 데이터입니다. 두 번째 인수는 데이터에 적용할 유효성 검증 규칙의 배열입니다.

요청의 유효성 검증 실패 여부를 확인한 후, withErrors 메소드를 사용하여 오류 메시지를 세션에 플래시할 수 있습니다. 이 메소드를 사용할 때, $errors 변수는 리디렉션 후 자동으로 뷰와 공유되어 사용자에게 쉽게 오류 메시지를 표시할 수 있습니다. withErrors 메소드는 validator, MessageBag 또는 PHP array를 인수로 받을 수 있습니다.

첫 번째 유효성 검증 실패 시 중지하기

stopOnFirstFailure 메소드는 단일 유효성 검증 실패가 발생하면 모든 속성의 유효성 검증을 중지하도록 Validator에 알립니다:

if ($validator->stopOnFirstFailure()->fails()) {
    // ...
}

5.1 자동 리디렉션[ | ]

HTTP 요청의 validate 메소드가 제공하는 자동 리디렉션 기능을 활용하면서도 수동으로 유효성 검증 인스턴스를 생성하려면, 기존 유효성 검증 인스턴스에서 validate 메소드를 호출할 수 있습니다. 유효성 검증이 실패하면 사용자는 자동으로 리디렉션되거나, XHR 요청의 경우 JSON 응답이 반환됩니다:

Validator::make($request->all(), [
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
])->validate();

유효성 검증이 실패했을 때 에러 메시지를 명명된 오류 백에 저장하려면 validateWithBag 메소드를 사용할 수 있습니다:

Validator::make($request->all(), [
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
])->validateWithBag('post');

5.2 명명된 오류 백[ | ]

한 페이지에 여러 개의 폼이 있는 경우, 유효성 검증 오류를 포함하는 MessageBag의 이름을 지정하여 특정 폼에 대한 오류 메시지를 조회할 수 있습니다. 이를 위해 withErrors에 두 번째 인수로 이름을 전달합니다:

return redirect('register')->withErrors($validator, 'login');

그런 다음 $errors 변수에서 명명된 MessageBag 인스턴스에 접근할 수 있습니다:

{{ $errors->login->first('email') }}

5.3 오류 메시지 커스터마이징[ | ]

필요에 따라, Laravel에서 제공하는 기본 오류 메시지 대신 커스텀 오류 메시지를 사용하도록 유효성 검증기 인스턴스를 설정할 수 있습니다. 커스텀 메시지를 지정하는 방법에는 여러 가지가 있습니다. 먼저, Validator::make 메소드의 세 번째 인자로 커스텀 메시지를 전달할 수 있습니다:

$validator = Validator::make($input, $rules, $messages = [
    'required' => 'The :attribute field is required.',
]);

이 예제에서 :attribute 플레이스홀더는 실제로 검증되는 필드의 이름으로 대체됩니다. 또한, 검증 메시지에서 다른 플레이스홀더도 사용할 수 있습니다. 예를 들어:

$messages = [
    'same' => 'The :attribute and :other must match.',
    'size' => 'The :attribute must be exactly :size.',
    'between' => 'The :attribute value :input is not between :min - :max.',
    'in' => 'The :attribute must be one of the following types: :values',
];
특정 속성에 대한 커스텀 메시지 지정

때때로 특정 속성에 대해서만 커스텀 오류 메시지를 지정하고 싶을 수 있습니다. 이 경우 "점(dot)" 표기법을 사용하여 지정할 수 있습니다. 속성 이름을 먼저 지정하고, 그 다음에 규칙을 지정합니다:

$messages = [
    'email.required' => 'We need to know your email address!',
];
커스텀 속성 값 지정

Laravel의 많은 기본 오류 메시지에는 :attribute 플레이스홀더가 포함되어 있으며, 이는 검증 중인 필드나 속성의 이름으로 대체됩니다. 특정 필드에 대해 이 플레이스홀더를 대체하는 값을 커스터마이징하려면, Validator::make 메소드의 네 번째 인자로 커스텀 속성 배열을 전달할 수 있습니다:

$validator = Validator::make($input, $rules, $messages, [
    'email' => 'email address',
]);

5.4 추가 유효성 검증 수행[ | ]

초기 검증이 완료된 후 추가 검증이 필요할 때가 있습니다. 이를 위해 validator의 after 메소드를 사용할 수 있습니다. after 메소드는 클로저나 호출가능(callable) 배열을 인자로 받아, 검증이 완료된 후 호출됩니다. 주어진 호출가능 객체들은 Illuminate\Validation\Validator 인스턴스를 전달받아, 필요한 경우 추가적인 오류 메시지를 발생시킬 수 있습니다:

use Illuminate\Support\Facades\Validator;

$validator = Validator::make(/* ... */);

$validator->after(function ($validator) {
    if ($this->somethingElseIsInvalid()) {
        $validator->errors()->add(
            'field', 'Something is wrong with this field!'
        );
    }
});

if ($validator->fails()) {
    // ...
}

언급했듯이, after 메소드는 호출가능 객체의 배열도 받을 수 있습니다. 이는 "검증 후" 로직이 호출가능 클래스에 캡슐화되어 있을 때 특히 유용합니다. 이 클래스들은 __invoke 메소드를 통해 Illuminate\Validation.Validator 인스턴스를 전달받습니다:

use App\Validation\ValidateShippingTime;
use App\Validation\ValidateUserStatus;

$validator->after([
    new ValidateUserStatus,
    new ValidateShippingTime,
    function ($validator) {
        // ...
    },
]);

6 유효성 검증된 입력 다루기[ | ]

폼 요청이나 수동으로 생성한 유효성 검증기 인스턴스를 사용하여 들어오는 요청 데이터를 유효성 검증한 후, 실제로 유효성 검증을 거친 요청 데이터를 조회하고 싶을 수 있습니다. 이는 여러 가지 방법으로 가능합니다. 먼저, 폼 요청이나 유효성 검증기 인스턴스에서 validated 메소드를 호출할 수 있습니다. 이 메소드는 유효성 검증을 거친 데이터를 배열 형태로 반환합니다:

$validated = $request->validated();
 
$validated = $validator->validated();

또는, 폼 요청이나 유효성 검증기 인스턴스에서 safe 메소드를 호출할 수 있습니다. 이 메소드는 Illuminate\Support\ValidatedInput 인스턴스를 반환합니다. 이 객체는 only, except, all 메소드를 노출하여 유효성 검증을 거친 데이터의 일부 또는 전체 배열을 조회할 수 있습니다:

$validated = $request->safe()->only(['name', 'email']);
 
$validated = $request->safe()->except(['name', 'email']);
 
$validated = $request->safe()->all();

또한, Illuminate\Support\ValidatedInput 인스턴스는 배열처럼 반복할 수 있고 접근할 수 있습니다:

// 유효성 검증된 데이터를 반복할 수 있습니다...
foreach ($request->safe() as $key => $value) {
    // ...
}
 
// 유효성 검증된 데이터에 배열처럼 접근할 수 있습니다...
$validated = $request->safe();
 
$email = $validated['email'];

유효성 검증된 데이터에 추가 필드를 추가하고 싶다면 merge 메소드를 호출할 수 있습니다:

$validated = $request->safe()->merge(['name' => 'Taylor Otwell']);

유효성 검증된 데이터를 콜렉션 인스턴스로 조회하고 싶다면 collect 메소드를 호출할 수 있습니다:

$collection = $request->safe()->collect();

7 오류 메시지 작업하기[ | ]

Validator 인스턴스에서 errors 메소드를 호출한 후에는 다양하고 편리한 메소드가 포함된 Illuminate\Support\MessageBag 인스턴스를 받게 됩니다. 모든 뷰에서 자동으로 제공되는 $errors 변수도 MessageBag 클래스의 인스턴스입니다.

필드의 첫 번째 오류 메시지 가져오기

주어진 필드에 대한 첫 번째 오류 메시지를 가져오려면 first 메소드를 사용합니다:

$errors = $validator->errors();
 
echo $errors->first('email');
필드의 모든 오류 메시지 가져오기

주어진 필드에 대한 모든 메시지의 배열을 가져와야 하는 경우, get 메소드를 사용합니다:

foreach ($errors->get('email') as $message) {
    // ...
}

배열 형식의 폼 필드를 검증하는 경우, * 문자를 사용하여 각 배열 요소에 대한 모든 메시지를 가져올 수 있습니다:

foreach ($errors->get('attachments.*') as $message) {
    // ...
}
모든 필드의 모든 오류 메시지 가져오기

모든 필드의 모든 메시지 배열을 가져오려면 all 메소드를 사용합니다:

foreach ($errors->all() as $message) {
    // ...
}
필드에 대한 메시지가 존재하는지 확인하기

has 메소드를 사용하여 주어진 필드에 대한 오류 메시지가 존재하는지 확인할 수 있습니다:

if ($errors->has('email')) {
    // ...
}

7.1 언어 파일에 커스텀 메시지 지정[ | ]

Laravel의 내장된 검증 규칙은 각각 애플리케이션의 lang/en/validation.php 파일에 위치한 오류 메시지를 가지고 있습니다. 애플리케이션에 lang 디렉토리가 없을 경우, lang:publish Artisan 명령어를 사용하여 Laravel이 해당 디렉토리를 생성하도록 지시할 수 있습니다.

lang/en/validation.php 파일 내에서 각 검증 규칙에 대한 번역 항목을 찾을 수 있습니다. 애플리케이션의 필요에 따라 이러한 메시지를 자유롭게 변경하거나 수정할 수 있습니다.

또한, 이 파일을 다른 언어 디렉터리로 복사하여 애플리케이션의 언어에 맞게 메시지를 번역할 수 있습니다. Laravel 현지화에 대해 더 자세히 알고 싶다면, 전체 현지화 문서를 참조하십시오.

Warning

기본적으로 Laravel 애플리케이션 스켈레톤에는 lang 디렉토리가 포함되어 있지 않습니다. Laravel의 언어 파일을 커스터마이즈하려면 lang:publish Artisan 명령어를 통해 이를 게시할 수 있습니다.

특정 속성에 대한 커스텀 메시지

애플리케이션의 검증 언어 파일에서 특정 속성과 규칙 조합에 사용되는 오류 메시지를 사용자 지정할 수 있습니다. 이를 위해 애플리케이션의 lang/xx/validation.php 언어 파일의 custom 배열에 메시지 커스터마이징을 추가하면 됩니다:

'custom' => [
    'email' => [
        'required' => 'We need to know your email address!',
        'max' => 'Your email address is too long!'
    ],
],

7.2 언어 파일에서 속성 지정[ | ]

Laravel의 많은 기본 오류 메시지에는 :attribute 자리표시자가 포함되어 있으며, 이는 유효성 검증 중인 필드 또는 속성의 이름으로 대체됩니다. 유효성 검증 메시지에서 :attribute 부분을 커스텀 값으로 대체하려면 lang/xx/validation.php 언어 파일의 attributes 배열에 커스텀 속성 이름을 지정할 수 있습니다:

'attributes' => [
    'email' => 'email address',
],

Warning

기본적으로 Laravel 애플리케이션 스켈레톤에는 lang 디렉토리가 포함되어 있지 않습니다. Laravel의 언어 파일을 커스터마이즈하려면 lang:publish Artisan 명령어를 통해 이를 게시할 수 있습니다.

7.3 언어 파일에서 값 지정[ | ]

Laravel의 일부 빌트인 유효성 검증 규칙 오류 메시지에는 현재 요청 속성의 값을 대체하는 :value 자리표시자가 포함되어 있습니다. 하지만 가끔은 유효성 검증 메시지의 :value 부분을 값의 커스텀 표현으로 대체해야 할 필요가 있습니다. 예를 들어, 다음 규칙을 생각해보세요. 이 규칙은 payment_typecc일 경우 신용카드 번호가 필수임을 지정합니다:

Validator::make($request->all(), [
    'credit_card_number' => 'required_if:payment_type,cc'
]);

이 유효성 검증 규칙이 실패하면 다음과 같은 오류 메시지가 생성됩니다:

The credit card number field is required when payment type is cc.

payment_type 값으로 cc를 표시하는 대신, lang/xx/validation.php 언어 파일에 values 배열을 정의하여 더 사용자 친화적인 값 표현을 지정할 수 있습니다:

'values' => [
    'payment_type' => [
        'cc' => 'credit card'
    ],
],

Warning

기본적으로 Laravel 애플리케이션 스켈레톤에는 lang 디렉토리가 포함되어 있지 않습니다. Laravel의 언어 파일을 사용자 정의하려면 lang:publish Artisan 명령어를 통해 이를 게시할 수 있습니다.

이 값을 정의한 후, 유효성 검증 규칙은 다음과 같은 오류 메시지를 생성할 것입니다:

The credit card number field is required when payment type is credit card.

8 사용가능한 유효성 검증 규칙[ | ]

아래는 사용가능한 모든 검증 규칙과 그 기능 목록입니다:

  • Accepted
  • Accepted If
  • Active URL
  • After (Date)
  • After Or Equal (Date)
  • Alpha
  • Alpha Dash
  • Alpha Numeric
  • Array
  • Ascii
  • Bail
  • Before (Date)
  • Before Or Equal (Date)
  • Between
  • Boolean
  • Confirmed
  • Contains
  • Current Password
  • Date
  • Date Equals
  • Date Format
  • Decimal
  • Declined
  • Declined If
  • Different
  • Digits
  • Digits Between
  • Dimensions (Image Files)
  • Distinct
  • Doesnt Start With
  • Doesnt End With
  • Email
  • Ends With
  • Enum
  • Exclude
  • Exclude If
  • Exclude Unless
  • Exclude With
  • Exclude Without
  • Exists (Database)
  • Extensions
  • File
  • Filled
  • Greater Than
  • Greater Than Or Equal
  • Hex Color
  • Image (File)
  • In
  • In Array
  • Integer
  • IP Address
  • JSON
  • Less Than
  • Less Than Or Equal
  • List
  • Lowercase
  • MAC Address
  • Max
  • Max Digits
  • MIME Types
  • MIME Type By File Extension
  • Min
  • Min Digits
  • Missing
  • Missing If
  • Missing Unless
  • Missing With
  • Missing With All
  • Multiple Of
  • Not In
  • Not Regex
  • Nullable
  • Numeric
  • Present
  • Present If
  • Present Unless
  • Present With
  • Present With All
  • Prohibited
  • Prohibited If
  • Prohibited Unless
  • Prohibits
  • Regular Expression
  • Required
  • Required If
  • Required If Accepted
  • Required If Declined
  • Required Unless
  • Required With
  • Required With All
  • Required Without
  • Required Without All
  • Required Array Keys
  • Same
  • Size
  • Sometimes
  • Starts With
  • String
  • Timezone
  • Unique (Database)
  • Uppercase
  • URL
  • ULID
  • UUID
accepted

검증 중인 필드는 "yes", "on", 1, "1", true, "true" 중 하나여야 합니다. 이는 "이용 약관" 동의와 같은 필드를 검증하는 데 유용합니다.

accepted_if:anotherfield,value,...

검증 중인 필드는 지정된 값과 일치하는 다른 필드가 있는 경우 "yes", "on", 1, "1", true, "true" 중 하나여야 합니다. 이는 "이용 약관" 동의와 같은 필드를 검증하는 데 유용합니다.

active_url

검증 중인 필드는 dns_get_record PHP 함수에 따라 유효한 A 또는 AAAA 레코드를 가져야 합니다. 제공된 URL의 호스트 이름은 parse_url PHP 함수를 사용하여 추출된 후 dns_get_record로 전달됩니다.

after:date

검증 대상 필드는 주어진 날짜 이후의 값이어야 합니다. 날짜는 strtotime PHP 함수를 통해 유효한 DateTime 인스턴스로 변환됩니다:

'start_date' => 'required|date|after:tomorrow'

날짜 문자열을 strtotime 함수로 평가하는 대신, 다른 필드를 지정하여 날짜를 비교할 수도 있습니다:

'finish_date' => 'required|date|after:start_date'
after_or_equal:date

검증 대상 필드는 주어진 날짜 이후 또는 같은 날짜의 값이어야 합니다. 자세한 내용은 after 규칙을 참조하십시오.

alpha

검증 대상 필드는 \p{L}\p{M}에 포함된 유니코드 알파벳 문자로만 구성되어야 합니다.

이 검증 규칙을 ASCII 범위 (a-zA-Z)로 제한하려면, ascii 옵션을 제공할 수 있습니다:

'username' => 'alpha:ascii',
alpha_dash

유효성 검사 필드에는 Unicode 알파숫자 문자\p{L}, \p{M}, \p{N}), ASCII 대시(-)와 ASCII 밑줄(_)만 포함되어야 합니다.

이 유효성 검증 규칙을 ASCII 범위의 문자(a-zA-Z)로 제한하려면 유효성 검증 규칙에 ascii 옵션을 제공할 수 있습니다:

'username' => 'alpha_dash:ascii',
alpha_num

유효성 검증 필드에는 Unicode 알파숫자 문자 \p{L}, \p{M}, \p{N}만 포함되어야 합니다.

이 유효성 검증 규칙을 ASCII 범위의 문자(a-zA-Z)로 제한하려면 유효성 검증 규칙에 ascii 옵션을 제공할 수 있습니다:

'username' => 'alpha_num:ascii',
array

유효성 검증 필드는 PHP array이어야 합니다.

array 규칙에 추가 값이 제공되면 입력 배열의 각 키는 규칙에 제공된 값 목록에 존재해야 합니다. 다음 예제에서 입력 배열의 admin 키는 array 규칙에 제공된 값 목록에 포함되지 않으므로 유효하지 않습니다:

use Illuminate\Support\Facades\Validator;

$input = [
    'user' => [
        'name' => 'Taylor Otwell',
        'username' => 'taylorotwell',
        'admin' => true,
    ],
];

Validator::make($input, [
    'user' => 'array:name,username',
]);

일반적으로 배열 내에 존재할 수 있는 배열 키를 항상 지정해야 합니다.

ascii

유효성 검증 필드는 완전히 7비트 ASCII 문자로 구성되어야 합니다.

bail

해당 필드에 대해 유효성 검증 실패가 발생하면 첫 번째 실패 후에 유효성 검증 규칙의 실행을 중단합니다.

bail 규칙은 특정 필드에서 유효성 검증 실패가 발생하면 해당 필드의 유효성 검증을 중단하지만, stopOnFirstFailure 메소드는 단일 유효성 검증 실패가 발생하면 모든 속성의 유효성 검증을 중단하도록 유효성 검증기에 지시합니다:

if ($validator->stopOnFirstFailure()->fails()) {
    // ...
}
before:date

해당 필드의 값은 지정된 날짜 이전이어야 합니다. 날짜는 PHP strtotime 함수로 전달되어 유효한 DateTime 인스턴스로 변환됩니다. 또한 after 규칙과 마찬가지로 유효성 검증 중인 다른 필드의 이름을 date 값으로 제공할 수 있습니다.

before_or_equal:date

해당 필드의 값은 지정된 날짜 이전이거나 동일해야 합니다. 날짜는 PHP strtotime 함수로 전달되어 유효한 DateTime 인스턴스로 변환됩니다. 또한 after 규칙과 마찬가지로 유효성 검증 중인 다른 필드의 이름을 date 값으로 제공할 수 있습니다.

between:min,max

해당 필드는 지정된 최소값과 최대값(포함) 사이의 크기를 가져야 합니다. 문자열, 숫자, 배열, 파일은 size 규칙과 동일한 방식으로 평가됩니다.

boolean

해당 필드는 boolean으로 변환될 수 있어야 합니다. 허용되는 입력 값은 true, false, 1, 0, "1", "0"입니다.

confirmed

검증 대상 필드는 {field}_confirmation 필드와 일치해야 합니다. 예를 들어, 검증 대상 필드가 password인 경우, 입력 값에 password_confirmation 필드가 있어야 합니다.

contains:foo,bar,...

검증 대상 필드는 주어진 매개변수 값을 모두 포함하는 배열이어야 합니다.

current_password

검증 대상 필드는 인증된 사용자의 패스워드와 일치해야 합니다. 규칙의 첫 번째 매개변수를 사용하여 인증 가드를 지정할 수 있습니다.

'password' => 'current_password:api'
date

검증 대상 필드는 strtotime PHP 함수에 따라 유효한 절대(non-relative) 날짜여야 합니다.

date_equals:date

검증 대상 필드는 주어진 날짜와 같아야 합니다. 날짜는 PHP strtotime 함수로 전달되어 유효한 DateTime 인스턴스로 변환됩니다.

date_format:format,...

검증 대상 필드는 주어진 형식 중 하나와 일치해야 합니다. 필드를 검증할 때 date 또는 date_format 중 하나를 사용해야 합니다. 이 검증 규칙은 PHP의 DateTime 클래스가 지원하는 모든 형식을 지원합니다.

declined

검증되는 필드는 "no", "off", 0, "0", false, "false" 여야 합니다.

declined_if:anotherfield,value,...

다른 필드의 값이 지정된 값과 같을 경우, 검증되는 필드는 "no", "off", 0, "0", false, "false" 여야 합니다.

different:field

검증되는 필드는 지정된 다른 필드와 다른 값을 가져야 합니다.

digits:value

검증되는 정수는 정확히 지정된 길이의 숫자여야 합니다.

digits_between:min,max

검증되는 정수는 지정된 최소 및 최대 길이 사이의 숫자여야 합니다.

dimensions

검증되는 파일은 지정된 차원 제약조건을 충족하는 이미지여야 합니다:

'avatar' => 'dimensions:min_width=100,min_height=200'

사용가능한 제약조건은 다음과 같습니다: min_width, max_width, min_height, max_height, width, height, ratio.

비율(ratio) 제약조건은 너비를 높이로 나눈 값으로 표현해야 합니다. 이는 3/2와 같은 분수 또는 1.5와 같은 부동소수점 수로 지정할 수 있습니다:

'avatar' => 'dimensions:ratio=3/2'

이 규칙은 여러 인수를 필요로 하므로 Rule::dimensions 메소드를 사용하여 규칙을 유창하게 구성할 수 있습니다:

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
Validator::make($data, [
    'avatar' => [
        'required',
        Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),
    ],
]);

9 조건부 규칙 추가[ | ]

10 배열 유효성 검증[ | ]

10.1 중첩 배열 입력 유효성 검증[ | ]

10.2 오류 메시지 인덱스 및 위치[ | ]

11 파일 유효성 검증[ | ]

12 패스워드 유효성 검증[ | ]

13 커스텀 유효성 검증 규칙[ | ]

13.1 규칙 객체 사용[ | ]

13.2 클로저 사용[ | ]

13.3 암시적 규칙[ | ]

문서 댓글 ({{ doc_comments.length }})
{{ comment.name }} {{ comment.created | snstime }}