유효성 검사
업데이트됨번역일: 2026년 9월 17일
이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.
- 원문 수정
- 2026년 9월 17일
- 번역 갱신
- 2026년 9월 17일
유효성 검사
소개
라라벨은 애플리케이션에 들어오는 데이터를 검증하는 여러 가지 방법을 제공합니다. 가장 흔히 사용하는 방법은 모든 HTTP 요청 객체에 내장되어 있는 validate 메서드를 사용하는 것입니다. 하지만 그 외에도 다양한 유효성 검사 방식을 함께 살펴보겠습니다.
라라벨은 데이터에 적용할 수 있는 다양한 편의 유효성 검사 규칙을 제공하며, 특정 데이터베이스 테이블에 값이 유일한지 검사하는 기능까지 지원합니다. 이 문서에서는 이러한 유효성 검사 규칙들을 하나하나 자세히 살펴보며, 라라벨이 제공하는 검증 기능을 충분히 익힐 수 있도록 안내합니다.
NOTE
이번 페이지는 시리즈의 1부입니다. 이어지는 섹션에서 유효성 검사 퀵스타트, Form Request, 유효성 검사기 수동 생성, 배열/파일 검증, 커스텀 규칙 작성 등을 순서대로 다룹니다.
다음 섹션에서는 유효성 검사 퀵스타트를 시작으로, 라우트 정의부터 컨트롤러 작성, 유효성 검사 로직 구현, 오류 메시지 표시, 폼 데이터 재입력(repopulate)까지 실전 예제를 통해 살펴보겠습니다.
NOTE
이후 섹션에서 #validation-quickstart, #quick-defining-the-routes, #quick-creating-the-controller, #quick-writing-the-validation-logic, #quick-displaying-the-validation-errors, #repopulating-forms, #a-note-on-optional-fields, #validation-error-response-format, #form-request-validation, #creating-form-requests, #authorizing-form-requests, #customizing-the-error-messages, #preparing-input-for-validation, #manually-creating-validators, #automatic-redirection, #named-error-bags, #manual-customizing-the-error-messages, #performing-additional-validation, #working-with-validated-input, #working-with-error-messages, #specifying-custom-messages-in-language-files, #specifying-attribute-in-language-files, #specifying-values-in-language-files, #available-validation-rules, #conditionally-adding-rules, #validating-arrays, #validating-nested-array-input, #error-message-indexes-and-positions, #validating-files, #validating-passwords, #custom-validation-rules, #using-rule-objects, #using-closures, #implicit-rules 앵커에 해당하는 내용을 순서대로 다룰 예정입니다.
유효성 검사
소개
Laravel은 애플리케이션에 들어오는 데이터를 검증하기 위한 다양한 방법을 제공합니다. 가장 흔히 사용되는 방식은 모든 HTTP 요청 객체에서 사용할 수 있는 validate 메서드지만, 이 외에도 여러 유효성 검사 방법을 함께 다루겠습니다.
Laravel에는 데이터 검증에 바로 활용할 수 있는 다양한 유효성 검사 규칙이 기본으로 포함되어 있습니다. 심지어 특정 데이터베이스 테이블 내에서 값이 유일한지(unique) 검사하는 규칙까지 제공합니다. 이 문서에서는 Laravel이 제공하는 유효성 검사 기능을 전부 익힐 수 있도록 각 규칙을 하나씩 자세히 설명합니다.
유효성 검사
유효성 검사 빠르게 시작하기
라라벨이 제공하는 강력한 유효성 검사 기능을 알아보기 위해, 폼을 검증하고 에러 메시지를 사용자에게 보여주는 전체 예제를 살펴보겠습니다. 이 개요를 읽고 나면 라라벨에서 들어오는 요청 데이터를 검증하는 방법에 대해 전반적으로 이해할 수 있게 될 것입니다.
라우트 정의하기
먼저 routes/web.php 파일에 다음과 같은 라우트가 정의되어 있다고 가정해 보겠습니다:
use App\Http\Controllers\PostController;
Route::get('/post/create', [PostController::class, 'create']);
Route::post('/post', [PostController::class, 'store']);GET 라우트는 사용자가 새 블로그 글을 작성할 수 있는 폼을 보여주며, POST 라우트는 새로 작성된 블로그 글을 데이터베이스에 저장합니다.
컨트롤러 작성하기
이제 이 라우트들로 들어오는 요청을 처리할 간단한 컨트롤러를 살펴보겠습니다. 일단 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]);
}
}유효성 검사 로직 작성하기
이제 새 블로그 글을 검증하는 로직으로 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 메서드에 전달됩니다. 사용 가능한 모든 유효성 검사 규칙은 문서에 정리되어 있으니 걱정하지 않아도 됩니다. 다시 말하지만, 검사가 실패하면 적절한 응답이 자동으로 생성됩니다. 검사가 통과되면 컨트롤러는 정상적으로 계속 실행됩니다.
또한, 이름이 지정된 에러 메시지 모음(named error bag)에 에러 메시지를 저장하면서 요청을 검증하고 싶다면 validateWithBag 메서드를 사용할 수 있습니다:
$validated = $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'],
]);반대로 필드 이름에 실제로 점(.) 문자가 포함되어 있다면, 백슬래시로 점을 이스케이프하여 "점 문법"으로 해석되지 않도록 명시적으로 지정할 수 있습니다:
$request->validate([
'title' => ['required', 'unique:posts', 'max:255'],
'v1\.0' => ['required'],
]);유효성 검사 에러 표시하기
그렇다면 들어오는 요청 필드가 지정된 유효성 검사 규칙을 통과하지 못하면 어떻게 될까요? 앞서 언급했듯이, 라라벨은 사용자를 자동으로 이전 위치로 리다이렉트시킵니다. 또한 모든 유효성 검사 에러와 요청 입력값이 자동으로 세션에 플래시됩니다.
web 미들웨어 그룹에 포함된 Illuminate\View\Middleware\ShareErrorsFromSession 미들웨어는 애플리케이션의 모든 뷰에 $errors 변수를 공유해줍니다. 이 미들웨어가 적용되면 뷰에서 항상 $errors 변수를 사용할 수 있으므로, 별도의 정의 없이도 안전하게 사용할 수 있다고 가정해도 됩니다. $errors 변수는 Illuminate\Support\MessageBag 인스턴스입니다. 이 객체를 다루는 방법에 대해서는 관련 문서를 참고하세요.
이제 예제로 돌아와서, 유효성 검사가 실패하면 사용자는 컨트롤러의 create 메서드로 리다이렉트되며, 뷰에서 에러 메시지를 다음과 같이 표시할 수 있습니다:
<!-- /resources/views/post/create.blade.php -->
<h1>글 작성</h1>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<!-- 글 작성 폼 -->에러 메시지 커스터마이징하기
라라벨에 내장된 각 유효성 검사 규칙에는 애플리케이션의 lang/en/validation.php 파일에 정의된 에러 메시지가 있습니다. 만약 애플리케이션에 lang 디렉터리가 없다면, lang:publish Artisan 명령어를 실행해 생성할 수 있습니다.
lang/en/validation.php 파일 안에는 각 유효성 검사 규칙에 대응하는 번역 항목이 있습니다. 애플리케이션의 요구 사항에 맞게 이 메시지들을 자유롭게 변경하거나 수정할 수 있습니다.
또한 이 파일을 다른 언어 디렉터리로 복사하여 애플리케이션 언어에 맞게 메시지를 번역할 수도 있습니다. 라라벨의 지역화(로컬라이제이션)에 대해 더 알고 싶다면 지역화 문서를 참고하세요.
WARNING
기본적으로 라라벨 애플리케이션 스켈레톤에는 lang 디렉터리가 포함되어 있지 않습니다. 라라벨의 언어 파일을 커스터마이징하고 싶다면 lang:publish Artisan 명령어로 파일들을 퍼블리시하면 됩니다.
XHR 요청과 유효성 검사
이 예제에서는 전통적인 폼을 사용해 애플리케이션에 데이터를 전송했습니다. 하지만 많은 애플리케이션은 자바스크립트 기반 프론트엔드에서 보내는 XHR 요청을 받습니다. XHR 요청 중에 validate 메서드를 사용하면 라라벨은 리다이렉트 응답을 생성하지 않습니다. 대신 모든 유효성 검사 에러를 담은 JSON 응답을 생성합니다. 이 JSON 응답은 422 HTTP 상태 코드와 함께 전송됩니다.
`@error` 디렉티브
Blade의 @error 디렉티브를 사용하면 특정 속성에 대한 유효성 검사 에러 메시지가 존재하는지 빠르게 확인할 수 있습니다. @error 디렉티브 안에서는 $message 변수를 출력해 에러 메시지를 표시할 수 있습니다:
<!-- /resources/views/post/create.blade.php -->
<label for="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이름이 지정된 에러 메시지 모음(named error bag)을 사용하고 있다면, @error 디렉티브의 두 번째 인자로 해당 에러 메시지 모음의 이름을 전달할 수 있습니다:
<input ... class="@error('title', 'post') is-invalid @enderror">입력값으로 폼 다시 채우기
유효성 검사 에러로 인해 라라벨이 리다이렉트 응답을 생성할 때, 프레임워크는 자동으로 요청의 모든 입력값을 세션에 플래시합니다. 이는 다음 요청에서 편리하게 입력값을 다시 가져와, 사용자가 제출하려던 폼을 이전 입력값으로 다시 채울 수 있도록 하기 위함입니다.
이전 요청에서 플래시된 입력값을 가져오려면 Illuminate\Http\Request 인스턴스의 old 메서드를 호출하면 됩니다. old 메서드는 세션에서 이전에 플래시된 입력 데이터를 가져옵니다:
$title = $request->old('title');라라벨은 전역 old 헬퍼 함수도 제공합니다. Blade 템플릿 안에서 이전 입력값을 표시할 때는 old 헬퍼를 사용하는 것이 더 편리합니다. 지정한 필드에 대한 이전 입력값이 없다면 null이 반환됩니다:
<input type="text" name="title" value="{{ old('title') }}">선택적(optional) 필드에 대한 참고 사항
라라벨은 기본적으로 애플리케이션의 전역 미들웨어 스택에 TrimStrings와 ConvertEmptyStringsToNull 미들웨어를 포함하고 있습니다. 이 때문에, null 값을 유효하지 않은 값으로 처리하지 않으려면 "선택적인" 요청 필드에는 nullable 규칙을 명시해줘야 하는 경우가 많습니다. 예를 들면:
$request->validate([
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
'publish_at' => ['nullable', 'date'],
]);이 예제에서는 publish_at 필드가 null이거나 유효한 날짜 형식이어야 한다고 지정하고 있습니다. 만약 규칙 정의에 nullable 수정자를 추가하지 않았다면, 유효성 검사기는 null을 유효하지 않은 날짜로 판단하게 됩니다.
유효성 검사 에러 응답 형식
애플리케이션에서 Illuminate\Validation\ValidationException 예외가 발생하고, 들어오는 HTTP 요청이 JSON 응답을 기대하고 있다면, 라라벨은 에러 메시지를 자동으로 형식화하여 422 Unprocessable Entity HTTP 응답으로 반환합니다.
아래는 유효성 검사 에러에 대한 JSON 응답 형식의 예시입니다. 중첩된 에러 키는 "점(dot)" 표기법 형식으로 평탄화(flatten)되어 표현된다는 점에 주의하세요:
{
"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."
]
}
}유효성 검사
폼 리퀘스트를 이용한 유효성 검사
폼 리퀘스트 생성하기
더 복잡한 유효성 검사가 필요한 경우, "폼 리퀘스트(form request)"를 만들어 사용하는 것을 고려해볼 만합니다. 폼 리퀘스트는 유효성 검사 로직과 인가(authorization) 로직을 캡슐화한 별도의 커스텀 요청 클래스입니다. 폼 리퀘스트 클래스는 make:request 아티즌 명령어로 생성할 수 있습니다.
php artisan make:request StorePostRequest생성된 폼 리퀘스트 클래스는 app/Http/Requests 디렉터리에 위치합니다. 만약 이 디렉터리가 존재하지 않는다면 make:request 명령어를 실행할 때 자동으로 생성됩니다. 라라벨이 생성하는 폼 리퀘스트 클래스에는 기본적으로 authorize와 rules라는 두 개의 메서드가 포함되어 있습니다.
이름에서 짐작할 수 있듯이 authorize 메서드는 현재 인증된 사용자가 해당 요청이 나타내는 작업을 수행할 권한이 있는지를 판단하는 역할을 하며, rules 메서드는 요청 데이터에 적용할 유효성 검사 규칙을 배열로 반환합니다.
/**
* 요청에 적용할 유효성 검사 규칙을 반환합니다.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
];
}NOTE
rules 메서드의 시그니처에 필요한 의존성을 타입힌트로 선언하면 라라벨 서비스 컨테이너를 통해 자동으로 해결됩니다.
그렇다면 이 유효성 검사 규칙은 실제로 언제, 어떻게 평가될까요? 컨트롤러 메서드에서 해당 폼 리퀘스트 클래스를 타입힌트로 지정하기만 하면 됩니다. 컨트롤러 메서드가 호출되기 전에 들어오는 요청에 대한 유효성 검사가 먼저 수행되므로, 컨트롤러 안에 유효성 검사 로직을 따로 작성할 필요가 없습니다.
/**
* 새 블로그 게시글을 저장합니다.
*/
public function store(StorePostRequest $request): RedirectResponse
{
// 요청 데이터는 이미 유효성 검사를 통과한 상태입니다...
// 검증된 입력 데이터를 가져옵니다...
$validated = $request->validated();
// 검증된 입력 데이터 중 일부만 가져옵니다...
$validated = $request->safe()->only(['name', 'email']);
$validated = $request->safe()->except(['name', 'email']);
// 블로그 게시글을 저장합니다...
return redirect('/posts');
}유효성 검사에 실패하면 사용자를 이전 페이지로 돌려보내는 리다이렉트 응답이 생성됩니다. 이때 오류 메시지는 세션에 플래시(flash)되어 화면에 표시할 수 있게 됩니다. 만약 요청이 XHR(비동기) 요청이었다면, 유효성 검사 오류의 JSON 표현을 담은 422 상태 코드의 HTTP 응답이 반환됩니다.
NOTE
Inertia 기반 라라벨 프런트엔드에서 실시간 폼 리퀘스트 유효성 검사가 필요하다면 Laravel Precognition을 확인해보세요.
추가 유효성 검사 수행하기
경우에 따라 기본 유효성 검사가 끝난 뒤에 추가적인 검증을 수행해야 할 때가 있습니다. 이런 경우에는 폼 리퀘스트의 after 메서드를 사용할 수 있습니다.
after 메서드는 유효성 검사가 완료된 후 호출될 콜러블(callable)이나 클로저의 배열을 반환해야 합니다. 이 콜러블들은 Illuminate\Validation\Validator 인스턴스를 인자로 받으므로, 필요하다면 추가적인 오류 메시지를 등록할 수 있습니다.
use Illuminate\Validation\Validator;
/**
* 요청에 대한 "after" 유효성 검사 콜러블 목록을 반환합니다.
*/
public function after(): array
{
return [
function (Validator $validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add(
'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 속성(attribute)을 추가하면, 하나의 속성(attribute)에서라도 검증 실패가 발생하는 즉시 나머지 속성에 대한 검증을 중단하도록 지정할 수 있습니다.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\Attributes\StopOnFirstFailure;
use Illuminate\Foundation\Http\FormRequest;
#[StopOnFirstFailure]
class StorePostRequest extends FormRequest
{
// ...
}정의되지 않은 필드가 있으면 실패 처리하기
요청 클래스에 FailOnUnknownFields 속성을 추가하면, 요청의 유효성 검사 규칙에 정의되지 않은 필드가 들어올 경우 라라벨이 이를 거부하도록 만들 수 있습니다.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\Attributes\FailOnUnknownFields;
use Illuminate\Foundation\Http\FormRequest;
#[FailOnUnknownFields]
class StorePostRequest extends FormRequest
{
public function rules(): array
{
return [
'title' => ['required', 'string'],
'body' => ['required', 'string'],
];
}
}AppServiceProvider에서 다음과 같이 작성하면 모든 폼 리퀘스트에 대해 이 동작을 전역적으로 활성화할 수도 있습니다.
use Illuminate\Foundation\Http\FormRequest;
/**
* 애플리케이션 서비스를 부트스트랩합니다.
*/
public function boot(): void
{
FormRequest::failOnUnknownFields();
}필요하다면 특정 요청 클래스에서는 속성에 false를 전달해 이 동작을 비활성화할 수도 있습니다.
#[FailOnUnknownFields(false)]
class PublicWebhookRequest extends FormRequest
{
// ...
}정의되지 않은 필드를 거부하도록 설정하면 예상치 못한 입력 키가 애플리케이션 내부 깊숙이 흘러 들어가는 것을 막아 매스 어사인먼트(mass-assignment)와 유사한 문제를 예방하는 데 도움이 됩니다. 다만 이 기능을 사용하더라도 모델의 $fillable / $guarded 속성은 반드시 함께 설정하고, 신뢰할 수 있는 검증된 입력값만 저장하도록 해야 합니다.
리다이렉트 위치 커스터마이징하기
폼 리퀘스트의 유효성 검사가 실패하면 사용자를 이전 페이지로 돌려보내는 리다이렉트 응답이 생성됩니다. 하지만 이 동작은 얼마든지 원하는 대로 바꿀 수 있습니다. 폼 리퀘스트 클래스에 RedirectTo 속성을 사용하면 됩니다.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\Attributes\RedirectTo;
use Illuminate\Foundation\Http\FormRequest;
#[RedirectTo('/dashboard')]
class StorePostRequest extends FormRequest
{
// ...
}또는 이름이 지정된 라우트로 리다이렉트하고 싶다면 RedirectToRoute 속성을 사용할 수 있습니다.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\Attributes\RedirectToRoute;
use Illuminate\Foundation\Http\FormRequest;
#[RedirectToRoute('dashboard')]
class StorePostRequest extends FormRequest
{
// ...
}오류 메시지 모음(Error Bag) 커스터마이징하기
폼 리퀘스트의 유효성 검사가 실패하면 오류 메시지는 default라는 이름의 에러 백(error bag)에 플래시됩니다. 만약 다른 이름이 지정된 에러 백에 오류를 저장하고 싶다면, 폼 리퀘스트 클래스에 ErrorBag 속성을 사용하면 됩니다.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\Attributes\ErrorBag;
use Illuminate\Foundation\Http\FormRequest;
#[ErrorBag('login')]
class LoginRequest extends FormRequest
{
// ...
}폼 리퀘스트 인가(Authorization) 처리하기
폼 리퀘스트 클래스에는 authorize 메서드도 포함되어 있습니다. 이 메서드 안에서는 인증된 사용자가 실제로 특정 리소스를 수정할 권한이 있는지 판단할 수 있습니다. 예를 들어, 사용자가 수정하려는 블로그 댓글이 실제로 본인이 작성한 것인지 확인하는 식입니다. 대부분의 경우 이 메서드 안에서 인가 게이트와 정책을 활용하게 될 것입니다.
use App\Models\Comment;
/**
* 사용자가 이 요청을 수행할 권한이 있는지 판단합니다.
*/
public function authorize(): bool
{
$comment = Comment::find($this->route('comment'));
return $comment && $this->user()->can('update', $comment);
}모든 폼 리퀘스트는 라라벨의 기본 요청 클래스를 확장하므로, user 메서드를 통해 현재 인증된 사용자에 접근할 수 있습니다. 그리고 위 예제에서 route 메서드를 호출하는 부분도 주목할 만합니다. 이 메서드를 사용하면 아래 라우트 정의의 {comment} 파라미터처럼 호출된 라우트에 정의된 URI 파라미터에 접근할 수 있습니다.
Route::post('/comment/{comment}');따라서 애플리케이션이 라우트 모델 바인딩을 사용하고 있다면, 아래와 같이 요청 객체의 프로퍼티로 이미 해석(resolve)된 모델에 바로 접근하는 방식으로 코드를 더 간결하게 작성할 수 있습니다.
return $this->user()->can('update', $this->comment);authorize 메서드가 false를 반환하면 403 상태 코드를 가진 HTTP 응답이 자동으로 반환되며, 컨트롤러 메서드는 실행되지 않습니다.
만약 요청에 대한 인가 로직을 애플리케이션의 다른 부분에서 처리할 계획이라면, authorize 메서드를 아예 제거하거나 단순히 true를 반환하도록 만들면 됩니다.
/**
* 사용자가 이 요청을 수행할 권한이 있는지 판단합니다.
*/
public function authorize(): bool
{
return true;
}NOTE
authorize 메서드의 시그니처에 필요한 의존성을 타입힌트로 선언하면 라라벨 서비스 컨테이너를 통해 자동으로 해결됩니다.
오류 메시지 커스터마이징하기
messages 메서드를 오버라이드하면 폼 리퀘스트에서 사용하는 오류 메시지를 원하는 대로 지정할 수 있습니다. 이 메서드는 속성(attribute)과 규칙(rule)의 조합을 키로 하고, 그에 대응하는 오류 메시지를 값으로 하는 배열을 반환해야 합니다.
/**
* 정의된 유효성 검사 규칙에 대한 오류 메시지를 반환합니다.
*
* @return array<string, string>
*/
public function messages(): array
{
return [
'title.required' => '제목은 필수 입력 항목입니다.',
'body.required' => '내용은 필수 입력 항목입니다.',
];
}유효성 검사 속성명 커스터마이징하기
라라벨에 내장된 대부분의 유효성 검사 오류 메시지에는 :attribute라는 플레이스홀더가 포함되어 있습니다. 이 :attribute 자리에 표시할 속성명을 원하는 이름으로 바꾸고 싶다면, attributes 메서드를 오버라이드해서 지정할 수 있습니다. 이 메서드는 속성명과 대체할 이름을 짝지은 배열을 반환해야 합니다.
/**
* 유효성 검사 오류에 사용할 커스텀 속성명을 반환합니다.
*
* @return array<string, string>
*/
public function attributes(): array
{
return [
'email' => '이메일 주소',
];
}유효성 검사 전 입력값 가공하기
유효성 검사 규칙을 적용하기 전에 요청 데이터를 가공하거나 정제해야 하는 경우, 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부)
Validator 인스턴스를 직접 생성하기
요청 객체의 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
{
/**
* Store a new blog post.
*/
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 메서드를 사용해 오류 메시지를 세션에 플래시(flash)할 수 있습니다. 이 메서드를 사용하면 리다이렉트 후 뷰에서 $errors 변수가 자동으로 공유되므로, 사용자에게 오류 메시지를 손쉽게 다시 보여줄 수 있습니다. withErrors 메서드는 validator 인스턴스, MessageBag, 또는 PHP 배열을 인자로 받을 수 있습니다.
첫 번째 유효성 검사 실패 시 중단하기
stopOnFirstFailure 메서드를 사용하면 하나의 속성에서라도 유효성 검사가 실패하는 즉시 나머지 속성에 대한 검사를 중단하도록 validator에게 지시할 수 있습니다:
if ($validator->stopOnFirstFailure()->fails()) {
// ...
}자동 리다이렉션
validator 인스턴스를 직접 생성하면서도 HTTP 요청의 validate 메서드가 제공하는 자동 리다이렉션 기능을 그대로 활용하고 싶다면, 이미 만들어진 validator 인스턴스에서 validate 메서드를 호출하면 됩니다. 유효성 검사에 실패하면 사용자는 자동으로 리다이렉트되며, XHR 요청인 경우에는 JSON 응답이 반환됩니다:
Validator::make($request->all(), [
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
])->validate();유효성 검사 실패 시 오류 메시지를 이름이 지정된 에러 백(named error bag)에 저장하고 싶다면 validateWithBag 메서드를 사용할 수 있습니다:
Validator::make($request->all(), [
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
])->validateWithBag('post');이름이 지정된 에러 백 (Named Error Bags)
한 페이지에 여러 개의 폼이 있는 경우, 각 폼에 대한 오류 메시지를 구분해서 가져올 수 있도록 유효성 검사 오류를 담은 MessageBag에 이름을 지정하고 싶을 수 있습니다. 이를 위해 withErrors의 두 번째 인자로 이름을 전달하면 됩니다:
return redirect('/register')->withErrors($validator, 'login');이렇게 하면 $errors 변수를 통해 이름이 지정된 MessageBag 인스턴스에 접근할 수 있습니다:
{{ $errors->login->first('email') }}NOTE
예를 들어 하나의 페이지에 로그인 폼과 회원가입 폼이 함께 있는 경우, 각각 login, register라는 이름을 지정해두면 어느 폼에서 발생한 오류인지 뷰에서 명확하게 구분해서 표시할 수 있습니다.
오류 메시지 커스터마이징
필요하다면 Laravel이 기본으로 제공하는 오류 메시지 대신 validator 인스턴스가 사용할 커스텀 오류 메시지를 지정할 수 있습니다. 커스텀 메시지를 지정하는 방법은 여러 가지가 있습니다. 먼저 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!',
];커스텀 속성 값(attribute) 지정하기
Laravel에 내장된 오류 메시지 중 상당수는 검사 대상 필드나 속성의 이름으로 치환되는 :attribute 플레이스홀더를 포함하고 있습니다. 특정 필드에 대해 이 플레이스홀더를 치환할 값을 커스터마이징하려면, Validator::make 메서드의 네 번째 인자로 커스텀 속성 배열을 전달하면 됩니다:
$validator = Validator::make($input, $rules, $messages, [
'email' => 'email address',
]);추가 유효성 검사 수행하기
기본 유효성 검사가 끝난 뒤 추가적인 검증 로직을 수행해야 할 때가 있습니다. 이때는 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 메서드는 콜러블 배열도 인자로 받을 수 있습니다. 이는 "검사 후 처리" 로직을 인보커블(invokable) 클래스로 캡슐화해둔 경우에 특히 유용한데, 이때 각 클래스는 __invoke 메서드를 통해 Illuminate\Validation\Validator 인스턴스를 전달받게 됩니다:
use App\Validation\ValidateShippingTime;
use App\Validation\ValidateUserStatus;
$validator->after([
new ValidateUserStatus,
new ValidateShippingTime,
function ($validator) {
// ...
},
]);유효성 검사
유효성이 검증된 입력 데이터 다루기
폼 리퀘스트나 직접 생성한 Validator 인스턴스로 요청 데이터의 유효성을 검증한 후에는, 실제로 검증을 통과한 데이터만 따로 가져오고 싶을 때가 있습니다. 이를 처리하는 방법은 여러 가지가 있습니다.
먼저, 폼 리퀘스트나 Validator 인스턴스에서 validated 메서드를 호출하면 검증을 통과한 데이터만 배열 형태로 반환받을 수 있습니다:
$validated = $request->validated();
$validated = $validator->validated();또는 폼 리퀘스트나 Validator 인스턴스에서 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();NOTE
validated()는 순수 배열을, safe()는 배열처럼 다룰 수 있는 객체(ValidatedInput)를 반환한다는 점이 차이입니다. 검증 결과에 추가 필드를 합치거나(merge), 컬렉션으로 바로 변환(collect)하고 싶을 때는 safe()를 사용하는 것이 더 편리합니다.
유효성 검사
오류 메시지 다루기
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')) {
// ...
}언어 파일에서 커스텀 메시지 지정하기
Laravel에 내장된 각 유효성 검사 규칙은 애플리케이션의 lang/en/validation.php 파일에 해당하는 오류 메시지를 가지고 있습니다. 만약 애플리케이션에 lang 디렉터리가 없다면, lang:publish Artisan 명령어를 실행해 생성할 수 있습니다.
lang/en/validation.php 파일 안에는 각 유효성 검사 규칙에 대응하는 번역 항목이 들어있습니다. 애플리케이션의 필요에 따라 이 메시지들을 자유롭게 변경하거나 수정할 수 있습니다.
또한 이 파일을 다른 언어 디렉터리로 복사하여 애플리케이션에서 사용하는 언어에 맞게 메시지를 번역할 수도 있습니다. Laravel의 로컬라이제이션에 대해 더 알고 싶다면 로컬라이제이션 문서를 참고하세요.
WARNING
기본적으로 Laravel 애플리케이션 스켈레톤에는 lang 디렉터리가 포함되어 있지 않습니다. Laravel의 언어 파일을 커스터마이징하려면 lang:publish Artisan 명령어로 먼저 언어 파일을 퍼블리시해야 합니다.
특정 속성에 대한 커스텀 메시지
애플리케이션의 유효성 검사 언어 파일에서 특정 속성(필드)과 규칙의 조합에 대해 사용할 오류 메시지를 커스터마이징할 수 있습니다. 이를 위해서는 lang/xx/validation.php 언어 파일의 custom 배열에 원하는 메시지를 추가하면 됩니다:
'custom' => [
'email' => [
'required' => '이메일 주소를 입력해 주세요!',
'max' => '이메일 주소가 너무 깁니다!'
],
],언어 파일에서 속성명 지정하기
Laravel에 내장된 여러 오류 메시지에는 :attribute 라는 플레이스홀더가 포함되어 있으며, 이 자리는 검증 대상 필드(속성)의 이름으로 치환됩니다. 유효성 검사 메시지에서 :attribute 부분을 원하는 값으로 바꾸고 싶다면, lang/xx/validation.php 언어 파일의 attributes 배열에 커스텀 속성명을 지정하면 됩니다:
'attributes' => [
'email' => '이메일 주소',
],WARNING
기본적으로 Laravel 애플리케이션 스켈레톤에는 lang 디렉터리가 포함되어 있지 않습니다. Laravel의 언어 파일을 커스터마이징하려면 lang:publish Artisan 명령어로 먼저 언어 파일을 퍼블리시해야 합니다.
언어 파일에서 값(Value) 지정하기
Laravel에 내장된 일부 유효성 검사 규칙의 오류 메시지에는 :value 라는 플레이스홀더가 포함되어 있으며, 이 자리는 요청 속성의 현재 값으로 치환됩니다. 하지만 경우에 따라 :value 부분을 값 그대로가 아니라 좀 더 이해하기 쉬운 표현으로 바꾸고 싶을 수 있습니다. 예를 들어, payment_type 값이 cc일 때 신용카드 번호(credit_card_number)를 필수로 지정하는 다음 규칙을 살펴보겠습니다:
Validator::make($request->all(), [
'credit_card_number' => ['required_if:payment_type,cc']
]);이 유효성 검사 규칙이 실패하면 다음과 같은 오류 메시지가 생성됩니다:
The credit card number field is required when payment type is cc.여기서 결제 수단 값으로 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.사용 가능한 유효성 검사 규칙
아래는 사용 가능한 모든 유효성 검사 규칙과 그 기능에 대한 목록입니다:
불리언
문자열
Active URL Alpha Alpha Dash Alpha Numeric Ascii Confirmed Current Password Different Doesnt Start With Doesnt End With Email Ends With Enum Hex Color In IP Address JSON Lowercase MAC Address Max Min Not In Regular Expression Not Regular Expression Same Size Starts With String Uppercase URL ULID UUID
숫자
Between Decimal Different Digits Digits Between Greater Than Greater Than Or Equal Integer Less Than Less Than Or Equal Max Max Digits Min Min Digits Multiple Of Numeric Same Size
배열
날짜
파일
Between Dimensions Encoding Extensions File Image Max Min MIME Types MIME Type By File Extension Size
Database
Utilities
Any Of Bail Exclude Exclude If Exclude Unless Exclude With Exclude Without Filled Missing Missing If Missing Unless Missing With Missing With All Nullable Present Present If Present Unless Present With Present With All Prohibited Prohibited If Prohibited If Accepted Prohibited If Declined Prohibited Unless Prohibits Required Required If Required If Accepted Required If Declined Required Unless Required With Required With All Required Without Required Without All Required Array Keys Sometimes
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에 전달됩니다.
active_url이나 email:dns와 같이 DNS 조회를 수행하는 유효성 검사 규칙을 테스트할 때는 Validator::fakeDnsLookups 메서드를 사용할 수 있습니다. 이 메서드는 규칙의 다른 유효성 검사 동작은 그대로 유지하면서 DNS 조회를 가짜로 처리합니다:
use Illuminate\Support\Facades\Validator;
Validator::fakeDnsLookups();after:_date_
검증 대상 필드는 주어진 날짜 이후의 값이어야 합니다. 날짜는 유효한 `DateTime` 인스턴스로 변환하기 위해 PHP의 `strtotime` 함수로 전달됩니다:'start_date' => ['required', 'date', 'after:tomorrow']strtotime으로 평가할 날짜 문자열을 전달하는 대신, 비교할 다른 필드를 지정할 수도 있습니다:
'finish_date' => ['required', 'date', 'after:start_date']편의를 위해, 날짜 기반 규칙은 플루언트한 date 규칙 빌더를 사용하여 구성할 수 있습니다:
use Illuminate\Validation\Rule;
'start_date' => [
'required',
Rule::date()->after(today()->addDays(7)),
],afterToday와 todayOrAfter 메서드는 각각 오늘 이후, 또는 오늘이거나 오늘 이후여야 함을 플루언트하게 표현하는 데 사용할 수 있습니다:
'start_date' => [
'required',
Rule::date()->afterToday(),
],after\_or\_equal:_date_
검증 대상 필드는 주어진 날짜 이후이거나 같은 값이어야 합니다. 자세한 내용은 after 규칙을 참고하세요.
편의를 위해, 날짜 기반 규칙은 플루언트한 date 규칙 빌더를 사용하여 구성할 수 있습니다:
use Illuminate\Validation\Rule;
'start_date' => [
'required',
Rule::date()->afterOrEqual(today()->addDays(7)),
],anyOf
`Rule::anyOf` 유효성 검사 규칙을 사용하면 유효성 검사 대상 필드가 주어진 유효성 검사 규칙 집합 중 하나를 만족해야 함을 지정할 수 있습니다. 예를 들어, 다음 규칙은 `username` 필드가 이메일 주소이거나 최소 6자 이상의 영숫자 문자열(대시 포함)인지 검증합니다:use Illuminate\Validation\Rule;
'username' => [
'required',
Rule::anyOf([
['string', 'email'],
['string', 'alpha_dash', 'min:6'],
]),
],alpha
유효성 검사 대상 필드는 \p{L}과 \p{M}에 포함된 유니코드 알파벳 문자로만 구성되어야 합니다.
이 유효성 검사 규칙을 ASCII 범위(a-z 및 A-Z)의 문자로 제한하려면, 유효성 검사 규칙에 ascii 옵션을 제공하면 됩니다:
'username' => ['alpha:ascii'],alpha_dash
유효성 검사 대상 필드는 \p{L}, \p{M}, \p{N}에 포함된 유니코드 영숫자 문자와 ASCII 대시(-) 및 ASCII 언더스코어(_)로만 구성되어야 합니다.
이 유효성 검사 규칙을 ASCII 범위(a-z, A-Z, 0-9)의 문자로 제한하려면, 유효성 검사 규칙에 ascii 옵션을 지정하면 됩니다:
'username' => ['alpha_dash:ascii'],alpha_num
유효성 검사 대상 필드는 전부 \p{L}, \p{M}, \p{N}에 포함된 유니코드 영숫자 문자여야 합니다.
이 유효성 검사 규칙을 ASCII 범위(a-z, A-Z, 0-9)의 문자로 제한하려면, 유효성 검사 규칙에 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'],
]);일반적으로 배열 안에 존재할 수 있는 배열 키를 항상 명시해야 합니다.
array_keys:_foo_,_bar_,...
유효성 검사 대상 필드는 그 키가 모두 주어진 목록에 포함된 PHP array여야 합니다. 최소한 하나의 키는 제공되어야 합니다:
'user' => ['array_keys:name,username'],편의를 위해 Rule::arrayKeys 메서드를 사용할 수 있습니다:
'user' => [Rule::arrayKeys('name', 'username')],ascii
유효성 검사 대상 필드는 전체가 7비트 ASCII 문자여야 합니다.
bail
첫 번째 유효성 검사 실패가 발생한 후 해당 필드에 대한 유효성 검사 규칙 실행을 중단합니다.
bail 규칙은 유효성 검사 실패가 발생했을 때 특정 필드에 대한 검사만 중단하지만, stopOnFirstFailure 메서드는 단 한 번이라도 유효성 검사 실패가 발생하면 모든 속성에 대한 검사를 중단하도록 validator에 알립니다:
if ($validator->stopOnFirstFailure()->fails()) {
// ...
}before:_date_
유효성 검사 대상 필드는 주어진 날짜보다 이전의 값이어야 합니다. 이 날짜는 PHP strtotime 함수에 전달되어 유효한 DateTime 인스턴스로 변환됩니다. 또한, after 규칙과 마찬가지로, date의 값으로 유효성 검사 대상인 다른 필드의 이름을 지정할 수도 있습니다.
편의를 위해, 날짜 기반 규칙은 fluent한 date 규칙 빌더를 사용하여 구성할 수도 있습니다:
undefineduse Illuminate\Validation\Rule;
'start_date' => [ 'required', Rule::date()->before(today()->subDays(7)), ],
`beforeToday` 및 `todayOrBefore` 메서드는 오늘 이전이어야 함, 또는 오늘이거나 오늘 이전이어야 함을 유창하게 표현하는 데 사용할 수 있습니다:
```php
'start_date' => [
'required',
Rule::date()->beforeToday(),
],before\_or\_equal:_date_
검사 중인 필드는 주어진 날짜보다 이전이거나 같은 값이어야 합니다. 날짜는 유효한 DateTime 인스턴스로 변환되기 위해 PHP strtotime 함수로 전달됩니다. 또한, after 규칙과 마찬가지로, date의 값으로 검사 중인 다른 필드의 이름을 지정할 수 있습니다.
편의를 위해, 날짜 기반 규칙은 유창한 date 규칙 빌더를 사용하여 구성할 수도 있습니다:
use Illuminate\Validation\Rule;
'start_date' => [
'required',
Rule::date()->beforeOrEqual(today()->subDays(7)),
],between:_min_,_max_
검사 중인 필드는 주어진 _min_과 max 사이(포함)의 크기를 가져야 합니다. 문자열, 숫자, 배열, 파일은 size 규칙과 동일한 방식으로 평가됩니다.
boolean
검사 중인 필드는 불리언으로 형변환될 수 있어야 합니다. 허용되는 입력값은 true, false, 1, 0, "1", "0"입니다.
strict 매개변수를 사용하면 값이 true 또는 false인 경우에만 유효한 것으로 간주하도록 할 수 있습니다:
'foo' => ['boolean:strict']confirmed
검증 대상 필드는 {field}_confirmation 형식의 일치하는 필드를 가지고 있어야 합니다. 예를 들어, 검증 대상 필드가 password라면, 입력값에 이와 일치하는 password_confirmation 필드가 존재해야 합니다.
사용자 정의 확인 필드 이름을 전달할 수도 있습니다. 예를 들어, confirmed:repeat_username을 사용하면 검증 대상 필드와 일치하는 repeat_username 필드가 있어야 합니다.
contains:_foo_,_bar_,...
검증 대상 필드는 주어진 매개변수 값을 모두 포함하는 배열이어야 합니다. 이 규칙은 종종 배열을 implode해야 하므로, Rule::contains 메서드를 사용하여 유연하게 규칙을 작성할 수 있습니다:
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
Validator::make($data, [
'roles' => [
'required',
'array',
Rule::contains(['admin', 'editor']),
],
]);doesnt_contain:_foo_,_bar_,...
검증 대상 필드는 주어진 매개변수 값 중 어느 것도 포함하지 않는 배열이어야 합니다. 이 규칙은 종종 배열을 implode해야 하므로, Rule::doesntContain 메서드를 사용하여 유연하게 규칙을 작성할 수 있습니다:
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
Validator::make($data, [
```php
'roles' => [
'required',
'array',
Rule::doesntContain(['admin', 'editor']),
],
]);current_password
검증 대상 필드는 인증된 사용자의 비밀번호와 일치해야 합니다. 규칙의 첫 번째 매개변수를 사용하여 인증 가드를 지정할 수 있습니다:
'password' => ['current_password:api']date
검증 대상 필드는 PHP의 strtotime 함수 기준으로 유효하며 상대적이지 않은 날짜여야 합니다.
date_equals:_date_
검증 대상 필드는 주어진 날짜와 같아야 합니다. 날짜는 유효한 DateTime 인스턴스로 변환하기 위해 PHP의 strtotime 함수로 전달됩니다.
date_format:_format_,...
검증 대상 필드는 주어진 formats 중 하나와 일치해야 합니다. 필드를 검증할 때는 date와 date_format 중 하나만 사용해야 하며, 둘 다 사용해서는 안 됩니다. 이 유효성 검사 규칙은 PHP의 DateTime 클래스가 지원하는 모든 포맷을 지원합니다.
편의를 위해, 날짜 기반 규칙은 유창한(fluent) date 규칙 빌더를 사용하여 구성할 수 있습니다:
use Illuminate\Validation\Rule;
'start_date' => [
'required',
Rule::date()->format('Y-m-d'),
],decimal:_min_,_max_
검증 대상 필드는 숫자여야 하며 지정된 소수점 자리수를 포함해야 합니다:
// Must have exactly two decimal places (9.99)...
'price' => ['decimal:2']
// Must have between 2 and 4 decimal places...
'price' => ['decimal:2,4']declined
검증 대상 필드는 "no", "off", 0, "0", false, 또는 "false"이어야 합니다.
declined_if:anotherfield,value,...
검증 대상 필드는 다른 필드가 지정된 값과 같을 경우 "no", "off", 0, "0", false, 또는 "false"이어야 합니다.
different:_field_
검증 대상 필드는 _field_와 다른 값을 가져야 합니다.
digits:_value_
검증 대상 정수는 정확히 value 자리 길이여야 합니다.
digits_between:_min_,_max_
검증 대상 정수는 주어진 _min_과 max 사이의 길이여야 합니다.
dimensions
검증 대상 파일은 규칙의 매개변수로 지정된 크기 제약 조건을 만족하는 이미지여야 합니다:
'avatar' => ['dimensions:min_width=100,min_height=200']사용 가능한 제약 조건은 다음과 같습니다: min_width, max_width, min_height, max_height, width, height, ratio, min_ratio, max_ratio.
ratio 제약 조건은 너비를 높이로 나눈 값으로 표현되어야 합니다. 이는 3/2와 같은 분수 또는 1.5와 같은 소수로 지정할 수 있습니다:
'avatar' => ['dimensions:ratio=3/2']_min_ratio_와 max_ratio 제약 조건은 허용 가능한 종횡비 범위를 정의하는 데 사용할 수 있습니다:
'avatar' => ['dimensions:min_ratio=1/2,max_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),
],
]);minRatio, maxRatio, ratioBetween 메서드를 사용하여 비율 제약 조건을 유연하게 정의할 수도 있습니다:
Rule::dimensions()->ratioBetween(min: 1 / 2, max: 3 / 2);distinct
배열의 유효성을 검사할 때, 검사 대상 필드에 중복된 값이 있으면 안 됩니다:
'foo.*.id' => ['distinct']Distinct는 기본적으로 느슨한(loose) 변수 비교를 사용합니다. 엄격한(strict) 비교를 사용하려면 유효성 검사 규칙 정의에 strict 매개변수를 추가하면 됩니다:
'foo.*.id' => ['distinct:strict']유효성 검사 규칙의 인수에 ignore_case를 추가하면 대소문자 차이를 무시하도록 만들 수 있습니다:
'foo.*.id' => ['distinct:ignore_case']doesnt_start_with:_foo_,_bar_,...
검사 대상 필드는 주어진 값들 중 하나로 시작해서는 안 됩니다.
doesnt_end_with:_foo_,_bar_,...
유효성 검사 대상 필드는 주어진 값들 중 하나로 끝나서는 안 됩니다.
유효성 검사 대상 필드는 이메일 주소 형식이어야 합니다. 이 유효성 검사 규칙은 이메일 주소를 검사하기 위해 egulias/email-validator 패키지를 사용합니다. 기본적으로는 RFCValidation 검사기가 적용되지만, 다른 검증 스타일을 적용할 수도 있습니다:
'email' => ['email:rfc,dns']위 예제는 RFCValidation과 DNSCheckValidation 검증을 적용합니다. 적용할 수 있는 검증 스타일의 전체 목록은 다음과 같습니다:
rfc:RFCValidation- 지원하는 RFC에 따라 이메일 주소를 검증합니다.strict:NoRFCWarningsValidation- 지원하는 RFC에 따라 이메일을 검증하며, 경고가 발견되면 실패합니다 (예: 마지막에 점이 있거나 연속된 점이 여러 개 있는 경우).dns:DNSCheckValidation- 이메일 주소의 도메인이 유효한 MX 레코드를 가지고 있는지 확인합니다.spoof:SpoofCheckValidation- 이메일 주소에 동형 문자나 기만적인 유니코드 문자가 포함되어 있지 않은지 확인합니다.filter:FilterEmailValidation- PHP의filter_var함수에 따라 이메일 주소가 유효한지 확인합니다.filter_unicode:FilterEmailValidation::unicode()- PHP의filter_var함수에 따라 일부 유니코드 문자를 허용하면서 이메일 주소가 유효한지 확인합니다.
편의를 위해, 이메일 유효성 검사 규칙은 fluent 규칙 빌더를 사용하여 만들 수 있습니다:
use Illuminate\Validation\Rule;
$request->validate([
'email' => [
'required',
Rule::email()
->rfcCompliant(strict: false)
->validateMxRecord()
->preventSpoofing()
],
]);dns 검사기는 실제 DNS 조회를 수행하여 주소의 도메인이 유효한 MX 레코드를 가지고 있는지 확인합니다. 개별 메일함이 존재하는지는 확인하지 않습니다.
테스트는 실제 DNS 조회에 의존해서는 안 되므로, Validator::fakeDnsLookups 메서드를 사용하여 DNS 조회를 가짜로 처리하면서, rfc와 같이 요청된 다른 유효성 검사는 계속 실행되도록 할 수 있습니다:
use Illuminate\Support\Facades\Validator;
Validator::fakeDnsLookups();이렇게 하면 테스트 중에도 애플리케이션이 기존 유효성 검사 규칙을 계속 사용할 수 있습니다:
'email' => ['required', 'email:rfc,dns'],WARNING
dns 및 spoof 검사기는 PHP intl 확장 모듈이 필요합니다.
encoding:*encoding_type*
검사 대상 필드는 지정된 문자 인코딩과 일치해야 합니다. 이 규칙은 PHP의 `mb_check_encoding` 함수를 사용하여 주어진 파일 또는 문자열 값의 인코딩을 확인합니다. 편의를 위해 `encoding` 규칙은 라라벨의 유연한 파일 규칙 빌더를 사용하여 작성할 수 있습니다:use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\File;
Validator::validate($input, [
'attachment' => [
'required',
File::types(['csv'])
->encoding('utf-8'),
],
]);ends_with:_foo_,_bar_,...
검사 대상 필드는 주어진 값 중 하나로 끝나야 합니다.
enum
Enum 규칙은 검사 대상 필드가 유효한 enum 값을 포함하는지 검증하는 클래스 기반 규칙입니다. Enum 규칙은 생성자 인수로 enum의 이름만을 받습니다. 원시 값을 검증할 때는 백드(backed) Enum을 Enum 규칙에 제공해야 합니다:
use App\Enums\ServerStatus;
use Illuminate\Validation\Rule;
$request->validate([
'status' => [Rule::enum(ServerStatus::class)],
]);Enum 규칙의 only와 except 메서드를 사용하여 어떤 enum case가 유효한 것으로 간주될지 제한할 수 있습니다:
Rule::enum(ServerStatus::class)
->only([ServerStatus::Pending, ServerStatus::Active]);
Rule::enum(ServerStatus::class)
->except([ServerStatus::Pending, ServerStatus::Active]);when 메서드를 사용하여 Enum 규칙을 조건부로 수정할 수 있습니다:
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\Rule;
Rule::enum(ServerStatus::class)
->when(
Auth::user()->isAdmin(),
fn ($rule) => $rule->only(...),
fn ($rule) => $rule->only(...),
);exclude
유효성 검사 대상 필드는 validate 및 validated 메서드가 반환하는 요청 데이터에서 제외됩니다.
exclude_if:_anotherfield_,_value_
유효성 검사 대상 필드는 anotherfield 필드가 value 와 같을 경우 validate 및 validated 메서드가 반환하는 요청 데이터에서 제외됩니다.
복잡한 조건부 제외 로직이 필요한 경우, Rule::excludeIf 메서드를 사용할 수 있습니다. 이 메서드는 불리언 또는 클로저를 인자로 받습니다. 클로저가 주어지면, 클로저는 유효성 검사 대상 필드가 제외되어야 하는지를 나타내기 위해 true 또는 false를 반환해야 합니다:
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
Validator::make($request->all(), [
'role_id' => [Rule::excludeIf($request->user()->is_admin)],
]);
Validator::make($request->all(), [
'role_id' => [Rule::excludeIf(fn () => $request->user()->is_admin)],
]);exclude_unless:_anotherfield_,_value_
_anotherfield_ 필드의 값이 _value_와 같지 않으면 검사 대상 필드는 `validate` 및 `validated` 메서드가 반환하는 요청 데이터에서 제외됩니다. 만약 _value_가 `null`(`exclude_unless:name,null`)이라면, 비교 대상 필드가 `null`이거나 요청 데이터에 존재하지 않는 경우가 아니라면 검사 대상 필드는 제외됩니다.복잡한 조건부 제외 로직이 필요하다면 Rule::excludeUnless 메서드를 활용할 수 있습니다. 이 메서드는 불리언 또는 클로저를 인자로 받습니다. 클로저가 주어지면, 검사 대상 필드가 제외되면 안 되는지 여부를 나타내기 위해 true 또는 false를 반환해야 합니다:
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
Validator::make($request->all(), [
'role_id' => [Rule::excludeUnless($request->user()->is_admin)],
]);
Validator::make($request->all(), [
'role_id' => [Rule::excludeUnless(fn () => $request->user()->is_admin)],
]);exclude_with:_anotherfield_
anotherfield 필드가 존재하면 검사 대상 필드는 validate 및 validated 메서드가 반환하는 요청 데이터에서 제외됩니다.
exclude_without:_anotherfield_
anotherfield 필드가 존재하지 않으면 검사 대상 필드는 validate 및 validated 메서드가 반환하는 요청 데이터에서 제외됩니다.
exists:_table_,_column_
당 필드는 지정된 데이터베이스 테이블에 존재해야 합니다.Exists 규칙의 기본 사용법
'state' => ['exists:states']column 옵션을 지정하지 않으면 필드 이름이 사용됩니다. 따라서 이 경우, 이 규칙은 states 데이터베이스 테이블에 요청의 state 속성 값과 일치하는 state 컬럼 값을 가진 레코드가 존재하는지 검사합니다.
사용자 지정 컬럼명 지정하기
데이터베이스 테이블 이름 뒤에 컬럼명을 명시하여 유효성 검사 규칙에서 사용할 데이터베이스 컬럼명을 직접 지정할 수 있습니다:
'state' => ['exists:states,abbreviation']때때로 exists 쿼리에 사용할 특정 데이터베이스 연결을 지정해야 할 수도 있습니다. 이 경우 테이블 이름 앞에 연결 이름을 붙이면 됩니다:
'email' => ['exists:connection.staff,email']테이블 이름을 직접 지정하는 대신, 테이블 이름을 결정하는 데 사용할 Eloquent 모델을 지정할 수도 있습니다:
'user_id' => ['exists:App\Models\User,id']유효성 검사 규칙에서 실행되는 쿼리를 커스터마이징하려면, Rule 클래스를 사용하여 규칙을 유연하게 정의할 수 있습니다.
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
Validator::make($data, [
'email' => [
'required',
```php
Rule::exists('staff')->where(function (Builder $query) {
$query->where('account_id', 1);
}),
],
]);Rule::exists 메서드로 생성된 exists 규칙이 사용해야 할 데이터베이스 컬럼명을 명시적으로 지정하려면, 컬럼명을 exists 메서드의 두 번째 인수로 전달하면 됩니다:
'state' => [Rule::exists('states', 'abbreviation')],때로는 값들의 배열이 데이터베이스에 존재하는지 검증하고 싶을 수도 있습니다. 이 경우 검증할 필드에 exists와 array 규칙을 함께 추가하면 됩니다:
'states' => ['array', Rule::exists('states', 'abbreviation')],이 두 규칙이 모두 하나의 필드에 지정되면, Laravel은 자동으로 지정된 테이블에 주어진 모든 값이 존재하는지 확인하는 단일 쿼리를 생성합니다.
extensions:_foo_,_bar_,...
검증 대상 파일은 나열된 확장자 중 하나에 해당하는 사용자 지정 확장자를 가져야 합니다:
'photo' => ['required', 'extensions:jpg,png'],WARNING
사용자 지정 확장자만으로 파일을 검증하는 것에 절대 의존해서는 안 됩니다. 이 규칙은 일반적으로 항상 mimes 또는 mimetypes 규칙과 함께 사용해야 합니다.
file
검증 대상 필드는 성공적으로 업로드된 파일이어야 합니다.
filled
validator = Validator::make($data, [ 'zones' => [ 'required', Rule::in(['first-zone', 'second-zone']), ], ]); ```When the in rule is combined with the array rule, each value in the input array must be present within the list of values provided to the in rule. In the following example, the LAS airport code in the input array is invalid since it is not contained within the list of airports provided to the in rule:
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
$input = [
'airports' => ['NYC', 'LAS'],
];
Validator::make($input, [
'airports' => [
'required',
'array',
],
'airports.*' => Rule::in(['NYC', 'LIT']),
]);in_array:_anotherfield_.*
The field under validation must exist in anotherfield's values.
integer
The field under validation must be an integer.
WARNING
This validation rule does not verify that the input is of the "integer" variable type, only that the input is of a type accepted by PHP's FILTER_VALIDATE_INT rule. If you need to validate the input as being a number please use this rule in combination with the numeric validation rule.
ip
The field under validation must be an IP address.
ipv4
The field under validation must be an IPv4 address.
ipv6
The field under validation must be an IPv6 address.
json
The field under validation must be a valid JSON string.
lt:_field_
The field under validation must be less than the given field. The two fields must be of the same type. Strings, numerics, arrays, and files are evaluated using the same conventions as the size rule.
lte:_field_
The field under validation must be less than or equal to the given field. The two fields must be of the same type. Strings, numerics, arrays, and files are evaluated using the same conventions as the size rule.
lowercase
The field under validation must be lowercase.
mac_address
The field under validation must be a MAC address.
max:_value_
The field under validation must be less than or equal to a maximum value. Strings, numerics, arrays, and files are evaluated in the same fashion as the size rule.
max_digits:_value_
The integer under validation must have a maximum length of value.
mimetypes:_text/plain_,...
The file under validation must match one of the given MIME types:
'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'To determine the MIME type of the uploaded file, the file's contents will be read and the framework will attempt to guess the MIME type, which may be different from the client's provided MIME type.
mimes:_foo_,_bar_,...
The file under validation must have a MIME type corresponding to one of the listed extensions.
Basic Usage of MIME Rule
'photo' => 'mimes:jpg,bmp,png'Even though you only need to specify the extensions, this rule actually validates the MIME type of the file by reading the file's contents and guessing its MIME type. A full listing of MIME types and their corresponding extensions may be found at the following location:
https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
min:_value_
The field under validation must have a minimum value. Strings, numerics, arrays, and files are evaluated in the same fashion as the size rule.
min_digits:_value_
The integer under validation must have a minimum length of value.
multiple_of:_value_
The field under validation must be a multiple of value.
missing
The field under validation must not be present in the input data.
missing_if:_anotherfield_,_value_,...
The field under validation must not be present if the anotherfield field is equal to any value.
missing_unless:_anotherfield_,_value_
The field under validation must not be present unless the anotherfield field is equal to any value.
missing_with:_foo_,_bar_,...
The field under validation must not be present only if any of the other specified fields are present.
missing_with_all:_foo_,_bar_,...
The field under validation must not be present only if all of the other specified fields are present.
not_in:_foo_,_bar_,...
The field under validation must not be included in the given list of values. The Rule::notIn method may be used to fluently construct the rule:
use Illuminate\Validation\Rule;
$validator = Validator::make($data, [
'toppings' => [
'required',
Rule::notIn(['sprinkles', 'cherries']),
],
]);regex:_pattern_
The field under validation must match the given regular expression.
Internally, this rule uses the PHP preg_match function. The pattern specified should obey the same formatting required by preg_match and thus also include valid delimiters. For example: 'email' => 'regex:/^.+@.+$/i'.
WARNING
When using the regex / not_regex patterns, it may be necessary to specify your validation rules using an array instead of using | delimiters, especially if the regular expression contains a | character.
not_regex:_pattern_
The field under validation must not match the given regular expression.
Internally, this rule uses the PHP preg_match function. The pattern specified should obey the same formatting required by preg_match and thus also include valid delimiters. For example: 'email' => 'not_regex:/^.+$/i'.
WARNING
When using the regex / not_regex patterns, it may be necessary to specify your validation rules using an array instead of using | delimiters, especially if the regular expression contains a | character.
Validator::make($data, [
'zones' => [
'required',
Rule::in(['first-zone', 'second-zone']),
],
]);in 규칙이 array 규칙과 결합되면, 입력 배열의 각 값은 in 규칙에 제공된 값 목록 내에 존재해야 합니다. 아래 예시에서 입력 배열의 LAS 공항 코드는 in 규칙에 제공된 공항 목록에 포함되어 있지 않으므로 유효하지 않습니다:
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
$input = [
'airports' => ['NYC', 'LAS'],
];
Validator::make($input, [
'airports' => [
'required',
'array',
],
'airports.*' => Rule::in(['NYC', 'LIT']),
]);in_array:_anotherfield_.*
검사 중인 필드는 _anotherfield_의 값들 안에 존재해야 합니다.
in_array_keys:_value_.*
검사 중인 필드는 배열이어야 하며, 주어진 values 중 최소 하나를 배열 내의 키로 가지고 있어야 합니다:
'config' => ['array', 'in_array_keys:timezone']integer
검사 중인 필드는 정수여야 합니다.
strict 매개변수를 사용하면 필드의 타입이 integer인 경우에만 유효한 것으로 간주할 수 있습니다. 정수 값을 가진 문자열은 유효하지 않은 것으로 간주됩니다:
'age' => ['integer:strict']WARNING
이 유효성 검사 규칙은 입력값이 "integer" 변수 타입인지를 검증하는 것이 아니라, 단지 PHP의 FILTER_VALIDATE_INT 규칙이 허용하는 타입인지만 검증합니다. 입력값이 숫자인지 검증해야 한다면 numeric 유효성 검사 규칙과 함께 이 규칙을 사용하세요.
ip
검증 대상 필드는 IP 주소여야 합니다.
ipv4
검증 대상 필드는 IPv4 주소여야 합니다.
ipv6
검증 대상 필드는 IPv6 주소여야 합니다.
json
검증 대상 필드는 유효한 JSON 문자열이어야 합니다.
lt:_field_
검증 대상 필드는 주어진 _field_보다 작아야 합니다. 두 필드는 같은 타입이어야 합니다. 문자열, 숫자, 배열, 파일은 size 규칙과 동일한 규칙으로 평가됩니다.
lte:_field_
검증 대상 필드는 주어진 _field_보다 작거나 같아야 합니다. 두 필드는 같은 타입이어야 합니다. 문자열, 숫자, 배열, 파일은 size 규칙과 동일한 규칙으로 평가됩니다.
lowercase
검증 대상 필드는 소문자여야 합니다.
list
검증 대상 필드는 리스트인 배열이어야 합니다. 배열의 키가 0부터 count($array) - 1까지 연속된 숫자로 구성되어 있으면 리스트로 간주됩니다.
mac_address
검증 대상 필드는 MAC 주소여야 합니다.
max:_value_
검증 대상 필드는 최대 value 이하여야 합니다. 문자열, 숫자, 배열, 파일은 size 규칙과 동일한 방식으로 평가됩니다.
max_digits:_value_
검증 대상 정수는 최대 value 길이를 가져야 합니다.
mimetypes:_text/plain_,...
검증 대상 파일은 주어진 MIME 타입 중 하나와 일치해야 합니다:
'video' => ['mimetypes:video/avi,video/mpeg,video/quicktime'],
'media' => ['mimetypes:image/*,video/*'],업로드된 파일의 MIME 타입을 결정하기 위해, 파일의 내용을 읽어 프레임워크가 MIME 타입을 추측하게 되는데, 이는 클라이언트가 제공한 MIME 타입과 다를 수 있습니다.
mimes:_foo_,_bar_,...
검증 대상 파일은 나열된 확장자 중 하나에 해당하는 MIME 타입을 가져야 합니다:
'photo' => ['mimes:jpg,bmp,png']확장자만 지정하면 되지만, 이 규칙은 실제로 파일의 내용을 읽고 MIME 타입을 추측하여 파일의 MIME 타입을 검증합니다. MIME 타입과 해당 확장자의 전체 목록은 다음 위치에서 확인할 수 있습니다:
https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
MIME 타입과 확장자
이 유효성 검사 규칙은 MIME 타입과 사용자가 파일에 지정한 확장자 간의 일치를 검증하지 않습니다. 예를 들어, mimes:png 유효성 검사 규칙은 파일 이름이 photo.txt라도 유효한 PNG 콘텐츠를 포함하고 있다면 유효한 PNG 이미지로 간주합니다. 사용자가 지정한 파일 확장자를 검증하려면 extensions 규칙을 사용할 수 있습니다.
min:_value_
검사 대상 필드는 최소 value 값을 가져야 합니다. 문자열, 숫자, 배열, 파일은 size 규칙과 동일한 방식으로 평가됩니다.
min_digits:_value_
검사 대상 정수는 최소 value 길이를 가져야 합니다.
multiple_of:_value_
검사 대상 필드는 _value_의 배수여야 합니다.
missing
검사 대상 필드는 입력 데이터에 존재하지 않아야 합니다.
missing_if:_anotherfield_,_value_,...
anotherfield 필드가 _value_와 같을 경우, 검사 대상 필드는 존재하지 않아야 합니다.
missing_unless:_anotherfield_,_value_
anotherfield 필드가 _value_와 같지 않으면, 검사 대상 필드는 존재하지 않아야 합니다.
missing_with:_foo_,_bar_,...
검증 대상 필드는 다른 지정된 필드 중 _하나라도_ 존재하는 경우에는 존재해서는 안 됩니다.missing_with_all:_foo_,_bar_,...
검증 대상 필드는 다른 지정된 필드가 모두 존재하는 경우에는 존재해서는 안 됩니다.
not_in:_foo_,_bar_,...
검증 대상 필드는 주어진 값 목록에 포함되어 있으면 안 됩니다. Rule::notIn 메서드를 사용하면 유연하게 규칙을 작성할 수 있습니다:
use Illuminate\Validation\Rule;
Validator::make($data, [
'toppings' => [
'required',
Rule::notIn(['sprinkles', 'cherries']),
],
]);not_regex:_pattern_
검증 대상 필드는 지정한 정규 표현식과 일치하면 안 됩니다.
내부적으로 이 규칙은 PHP의 preg_match 함수를 사용합니다. 지정한 패턴은 preg_match가 요구하는 형식을 따라야 하며, 그에 맞는 유효한 구분자를 포함해야 합니다. 예를 들어: 'email' => ['not_regex:/^.+$/i'].
nullable
검증 대상 필드는 null일 수 있습니다.
numeric
검증 대상 필드는 숫자여야 합니다.
strict 매개변수를 사용하면 필드 값이 정수나 실수 타입일 때만 유효한 것으로 간주할 수 있습니다. 숫자로 이루어진 문자열은 유효하지 않은 것으로 처리됩니다:
'amount' => ['numeric:strict']present
검사 대상 필드는 입력 데이터에 존재해야 합니다.present_if:_anotherfield_,_value_,...
anotherfield 필드가 value 중 하나와 같을 경우, 검사 대상 필드는 존재해야 합니다.
present_unless:_anotherfield_,_value_
anotherfield 필드가 value 중 하나와 같지 않은 경우, 검사 대상 필드는 존재해야 합니다.
present_with:_foo_,_bar_,...
다른 지정된 필드 중 하나라도 존재하는 경우에만 검사 대상 필드가 존재해야 합니다.
present_with_all:_foo_,_bar_,...
다른 지정된 필드가 모두 존재하는 경우에만 검사 대상 필드가 존재해야 합니다.
prohibited
검사 대상 필드는 존재하지 않거나 비어 있어야 합니다. 필드가 다음 중 하나의 조건을 만족하면 "비어 있음"으로 간주됩니다.
- 값이
null인 경우. - 값이 빈 문자열인 경우.
- 값이 빈 배열이거나 빈
Countable객체인 경우. - 값이 경로가 없는 업로드된 파일인 경우.
prohibited_if:_anotherfield_,_value_,...
anotherfield 필드가 value 중 하나와 같을 경우, 검사 대상 필드는 존재하지 않거나 비어 있어야 합니다. 필드가 다음 중 하나의 조건을 만족하면 "비어 있음"으로 간주됩니다.
-
값이
null인 경우. -
값이 빈 문자열인 경우.
-
The value is an empty array or empty
Countableobject. -
The value is an uploaded file with an empty path.
복잡한 조건부 금지 로직이 필요한 경우, Rule::prohibitedIf 메서드를 활용할 수 있습니다. 이 메서드는 불리언 값 또는 클로저를 받습니다. 클로저가 주어진 경우, 클로저는 검증 대상 필드가 금지되어야 하는지를 나타내기 위해 true 또는 false를 반환해야 합니다:
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
Validator::make($request->all(), [
'role_id' => [Rule::prohibitedIf($request->user()->is_admin)],
]);
Validator::make($request->all(), [
'role_id' => [Rule::prohibitedIf(fn () => $request->user()->is_admin)],
]);prohibited_if_accepted:_anotherfield_,...
검증 대상 필드는 anotherfield 필드가 "yes", "on", 1, "1", true, 또는 "true"와 같을 경우 반드시 존재하지 않거나 비어 있어야 합니다.
prohibited_if_declined:_anotherfield_,...
검증 대상 필드는 anotherfield 필드가 "no", "off", 0, "0", false, 또는 "false"와 같을 경우 반드시 존재하지 않거나 비어 있어야 합니다.
prohibited_unless:_anotherfield_,_value_,...
검증 대상 필드는 anotherfield 필드가 value 중 어느 하나와 같지 않는 한 반드시 존재하지 않거나 비어 있어야 합니다. 필드가 "비어 있다"는 것은 다음 기준 중 하나를 충족하는 경우를 의미합니다:
- 값이
null인 경우. - 값이 빈 문자열인 경우.
- 값이 빈 배열이거나 빈
Countable객체인 경우. - 값이 빈 경로를 가진 업로드된 파일인 경우.
복잡한 조건부 금지 로직이 필요한 경우, Rule::prohibitedUnless 메서드를 활용할 수 있습니다. 이 메서드는 불리언 또는 클로저를 인자로 받습니다. 클로저가 주어진 경우, 해당 클로저는 검사 대상 필드가 금지되지 않아야 하는지를 나타내기 위해 true 또는 false를 반환해야 합니다:
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
Validator::make($request->all(), [
'role_id' => [Rule::prohibitedUnless($request->user()->is_admin)],
]);
Validator::make($request->all(), [
'role_id' => [Rule::prohibitedUnless(fn () => $request->user()->is_admin)],
]);prohibits:_anotherfield_,...
검사 대상 필드가 누락되지 않거나 비어 있지 않은 경우, anotherfield 에 있는 모든 필드는 누락되거나 비어 있어야 합니다. 필드가 다음 기준 중 하나를 충족하면 "비어 있다"고 간주됩니다:
- 값이
null인 경우. - 값이 빈 문자열인 경우.
- 값이 빈 배열이거나 빈
Countable객체인 경우. - 값이 빈 경로를 가진 업로드된 파일인 경우.
regex:_pattern_
검사 대상 필드는 주어진 정규 표현식과 일치해야 합니다.
내부적으로 이 규칙은 PHP의 preg_match 함수를 사용합니다. 지정한 패턴은 preg_match에 필요한 형식을 따라야 하며, 따라서 유효한 구분자도 포함해야 합니다. 예를 들면: 'email' => ['regex:/^.+@.+$/i'].
required
검증 대상 필드는 입력 데이터에 존재해야 하며 비어 있지 않아야 합니다. 필드는 다음 조건 중 하나를 충족할 때 "비어 있음"으로 간주됩니다:
- 값이
null인 경우. - 값이 빈 문자열인 경우.
- 값이 빈 배열이거나 빈
Countable객체인 경우. - 값이 경로가 없는 업로드된 파일인 경우.
required_if:_anotherfield_,_value_,...
검증 대상 필드는 anotherfield 필드의 값이 어떤 value 와 같을 경우, 반드시 존재해야 하며 비어 있지 않아야 합니다.
required_if 규칙에 대해 더 복잡한 조건을 구성하고 싶다면 Rule::requiredIf 메서드를 사용할 수 있습니다. 이 메서드는 불리언 또는 클로저를 인자로 받습니다. 클로저가 전달되는 경우, 해당 클로저는 검증 대상 필드가 필수인지 여부를 나타내기 위해 true 또는 false를 반환해야 합니다:
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
Validator::make($request->all(), [
'role_id' => [Rule::requiredIf($request->user()->is_admin)],
]);
Validator::make($request->all(), [
'role_id' => [Rule::requiredIf(fn () => $request->user()->is_admin)],
]);required_if_accepted:_anotherfield_,...
검증 대상 필드는 _anotherfield_ 필드가 `"yes"`, `"on"`, `1`, `"1"`, `true`, `"true"` 중 하나와 같은 경우 반드시 존재해야 하며 비어 있지 않아야 합니다.required_if_declined:_anotherfield_,...
검증 대상 필드는 anotherfield 필드가 "no", "off", 0, "0", false, "false" 중 하나와 같은 경우 반드시 존재해야 하며 비어 있지 않아야 합니다.
required_unless:_anotherfield_,_value_,...
검증 대상 필드는 anotherfield 필드가 어떤 _value_와도 같지 않은 경우 반드시 존재해야 하며 비어 있지 않아야 합니다. 이는 또한 _value_가 null이 아닌 한 _anotherfield_가 요청 데이터에 존재해야 함을 의미합니다. _value_가 null인 경우(required_unless:name,null), 비교 대상 필드가 null이거나 요청 데이터에서 누락된 경우가 아니라면 검증 대상 필드는 필수가 됩니다.
required_unless 규칙에 대해 더 복잡한 조건을 구성하고 싶다면, Rule::requiredUnless 메서드를 사용할 수 있습니다. 이 메서드는 불리언 또는 클로저를 받습니다. 클로저가 전달되는 경우, 클로저는 검증 대상 필드가 필수가 아님을 나타내기 위해 true 또는 false를 반환해야 합니다:
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
Validator::make($request->all(), [
'role_id' => [Rule::requiredUnless($request->user()->is_admin)],
]);
Validator::make($request->all(), [
'role_id' => [Rule::requiredUnless(fn () => $request->user()->is_admin)],
]);required_with:_foo_,_bar_,...
검증 대상 필드는 지정된 다른 필드 중 하나라도 존재하고 비어 있지 않은 경우에 한해 반드시 존재해야 하며 비어 있지 않아야 합니다.
required_with_all:_foo_,_bar_,...
검증 대상 필드는 지정된 다른 필드가 모두 존재하고 비어 있지 않은 경우에 한해 반드시 존재해야 하며 비어 있지 않아야 합니다.
required_without:_foo_,_bar_,...
검증 대상 필드는 지정된 다른 필드 중 하나라도 비어 있거나 존재하지 않는 경우에 한해 반드시 존재해야 하며 비어 있지 않아야 합니다.
required_without_all:_foo_,_bar_,...
검증 대상 필드는 지정된 다른 필드가 모두 비어 있거나 존재하지 않는 경우에 한해 반드시 존재해야 하며 비어 있지 않아야 합니다.
required_array_keys:_foo_,_bar_,...
검증 대상 필드는 배열이어야 하며 최소한 지정된 키들을 포함해야 합니다.
same:field
주어진 _field_는 검증 대상 필드와 일치해야 합니다.
size:value
유효성 검사 대상 필드는 지정된 _value_와 일치하는 크기를 가져야 합니다. 문자열 데이터의 경우, _value_는 문자 수에 해당합니다. 숫자 데이터의 경우, _value_는 지정된 정수 값에 해당합니다(해당 속성에는 numeric 또는 integer 규칙도 있어야 합니다). 배열의 경우, _size_는 배열의 count에 해당합니다. 파일의 경우, _size_는 킬로바이트 단위의 파일 크기에 해당합니다. 몇 가지 예를 살펴보겠습니다:
// Validate that a string is exactly 12 characters long...
'title' => ['size:12'];
// Validate that a provided integer equals 10...
'seats' => ['integer', 'size:10'];
// Validate that an array has exactly 5 elements...
'tags' => ['array', 'size:5'];
// Validate that an uploaded file is exactly 512 kilobytes...
'image' => ['file', 'size:512'];starts_with:_foo_,_bar_,...
유효성 검사 대상 필드는 지정된 값 중 하나로 시작해야 합니다.
string
유효성 검사 대상 필드는 문자열이어야 합니다. 필드가 null도 허용하도록 하려면 해당 필드에 nullable 규칙을 지정해야 합니다.
편의를 위해, 문자열 유효성 검사 규칙은 플루언트한 Rule::string() 규칙 빌더를 사용해 구성할 수도 있습니다:
use Illuminate\Validation\Rule;
'title' => [
'required',
Rule::string()
->min(3)
->max(255)
->alphaDash(ascii: true),
],문자열 규칙 빌더는 alpha, alphaDash, alphaNumeric, ascii, between, doesntEndWith, doesntStartWith, endsWith, exactly, lowercase, max, min, startsWith, uppercase를 포함하여 일반적인 문자열 제약 조건을 위한 메서드를 제공합니다. 규칙 빌더는 conditionable(조건부 처리 가능)하므로, when과 unless 메서드를 사용하여 조건에 따라 제약 조건을 적용할 수도 있습니다.
timezone
유효성 검사 대상 필드는 DateTimeZone::listIdentifiers 메서드에 따른 유효한 타임존 식별자여야 합니다.
DateTimeZone::listIdentifiers 메서드가 허용하는 인자를 이 유효성 검사 규칙에도 제공할 수 있습니다:
'timezone' => ['required', 'timezone:all'];
'timezone' => ['required', 'timezone:Africa'];
'timezone' => ['required', 'timezone:per_country,US'];unique:table,column
유효성 검사 대상 필드는 주어진 데이터베이스 테이블 내에 존재하지 않아야 합니다.
커스텀 테이블 / 컬럼명 지정하기:
테이블명을 직접 지정하는 대신, 테이블명을 결정하는 데 사용할 Eloquent 모델을 지정할 수 있습니다:
'email' => ['unique:App\Models\User,email_address']column 옵션을 사용하여 필드에 대응하는 데이터베이스 컬럼을 지정할 수 있습니다. column 옵션을 지정하지 않으면 유효성 검사 대상 필드의 이름이 사용됩니다.
'email' => ['unique:users,email_address']사용자 정의 데이터베이스 연결 지정하기
경우에 따라 Validator가 실행하는 데이터베이스 쿼리에 대해 사용자 정의 연결을 설정해야 할 수도 있습니다. 이를 위해서는 테이블 이름 앞에 연결 이름을 붙이면 됩니다:
'email' => ['unique:connection.users,email_address']지정된 ID를 무시하도록 unique 규칙 강제하기:
때로는 unique 검증 시 지정된 ID를 무시하고 싶을 수 있습니다. 예를 들어, 사용자의 이름, 이메일 주소, 위치를 포함하는 "프로필 수정" 화면을 생각해봅시다. 아마도 이메일 주소가 고유한지 확인하고 싶을 것입니다. 하지만 사용자가 이름 필드만 변경하고 이메일 필드는 변경하지 않은 경우, 사용자가 이미 해당 이메일 주소의 소유자이기 때문에 유효성 검사 오류가 발생하지 않기를 원할 것입니다.
사용자의 ID를 무시하도록 유효성 검사기에 지시하려면, Rule 클래스를 사용하여 규칙을 유연하게 정의합니다.
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
]);WARNING
사용자가 제어하는 요청 입력값을 ignore 메서드에 전달해서는 안 됩니다. 대신, Eloquent 모델 인스턴스의 자동 증가 ID나 UUID와 같이 시스템에서 생성된 고유 ID만 전달해야 합니다. 그렇지 않으면 애플리케이션이 SQL 인젝션 공격에 취약해질 수 있습니다.
ignore 메서드에 모델 키의 값을 전달하는 대신, 모델 인스턴스 전체를 전달할 수도 있습니다. Laravel이 자동으로 모델에서 키를 추출합니다:
Rule::unique('users')->ignore($user);테이블이 id가 아닌 다른 기본 키 컬럼명을 사용하는 경우, ignore 메서드를 호출할 때 해당 컬럼의 이름을 지정할 수 있습니다:
Rule::unique('users')->ignore($user->id, 'user_id');기본적으로 unique 규칙은 검증 대상 속성의 이름과 일치하는 컬럼의 고유성을 검사합니다. 하지만 unique 메서드의 두 번째 인수로 다른 컬럼명을 전달할 수도 있습니다:
Rule::unique('users', 'email_address')->ignore($user->id);추가 Where 절 추가하기:
where 메서드를 사용해 쿼리를 커스터마이징하여 추가적인 쿼리 조건을 지정할 수 있습니다. 예를 들어, account_id 컬럼 값이 1인 레코드만 검색하도록 쿼리 범위를 지정하는 조건을 추가해 보겠습니다:
'email' => Rule::unique('users')->where(fn (Builder $query) => $query->where('account_id', 1))고유성 검사에서 소프트 삭제된 레코드 제외하기:
기본적으로 unique 규칙은 고유성을 판단할 때 소프트 삭제된 레코드도 포함합니다. 고유성 검사에서 소프트 삭제된 레코드를 제외하려면, withoutTrashed 메서드를 호출하면 됩니다:
Rule::unique('users')->withoutTrashed();모델에서 소프트 삭제된 레코드에 대해 deleted_at이 아닌 다른 컬럼명을 사용하는 경우, withoutTrashed 메서드를 호출할 때 컬럼명을 지정할 수 있습니다:
Rule::unique('users')->withoutTrashed('was_deleted_at');uppercase
검증 대상 필드는 대문자여야 합니다.
url
검증 대상 필드는 유효한 URL이어야 합니다.
유효한 것으로 간주되어야 할 URL 프로토콜을 지정하고 싶다면, 유효성 검사 규칙의 매개변수로 프로토콜을 전달할 수 있습니다:
'url' => ['url:http,https'],
'game' => ['url:minecraft,steam'],ulid
검증 대상 필드는 유효한 Universally Unique Lexicographically Sortable Identifier (ULID)여야 합니다.
uuid
검증 대상 필드는 유효한 RFC 9562 (버전 1, 3, 4, 5, 6, 7, 또는 8) universally unique identifier (UUID)여야 합니다.
또한 주어진 UUID가 특정 버전의 UUID 스펙과 일치하는지 검증할 수도 있습니다:
'uuid' => ['uuid:4']조건부로 규칙 추가하기
특정 값을 가질 때 유효성 검사 건너뛰기
다른 필드가 특정 값을 가지고 있을 때, 어떤 필드는 유효성 검사에서 아예 제외하고 싶은 경우가 있습니다. 이럴 때는 exclude_if 유효성 검사 규칙을 사용하면 됩니다. 아래 예제에서는 has_appointment 필드 값이 false이면 appointment_date와 doctor_name 필드는 검사 대상에서 제외됩니다:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($data, [
'has_appointment' => ['required', 'boolean'],
'appointment_date' => ['exclude_if:has_appointment,false', 'required', 'date'],
'doctor_name' => ['exclude_if:has_appointment,false', 'required', 'string'],
]);반대로, 특정 필드가 특정 값을 가지지 않을 때 검사를 제외하고 싶다면 exclude_unless 규칙을 사용할 수 있습니다:
$validator = Validator::make($data, [
'has_appointment' => ['required', 'boolean'],
'appointment_date' => ['exclude_unless:has_appointment,true', 'required', 'date'],
'doctor_name' => ['exclude_unless:has_appointment,true', 'required', 'string'],
]);필드가 존재할 때만 검사하기
경우에 따라 어떤 필드가 검사 대상 데이터에 존재할 때만 유효성 검사를 수행하고 싶을 수 있습니다. 이럴 때는 규칙 목록에 sometimes 규칙을 추가하면 간단히 해결됩니다:
$validator = Validator::make($data, [
'email' => ['sometimes', 'required', 'email'],
]);위 예제에서 email 필드는 $data 배열에 실제로 존재할 때만 유효성 검사가 이루어집니다.
NOTE
항상 존재해야 하지만 값이 비어 있을 수도 있는 필드를 검사하려는 경우라면, 선택적 필드에 대한 참고 사항을 확인해보세요.
복잡한 조건부 유효성 검사
때로는 더 복잡한 조건 로직에 따라 유효성 검사 규칙을 추가해야 할 수도 있습니다. 예를 들어 어떤 필드의 값이 100보다 클 때만 다른 필드를 필수로 만들고 싶거나, 특정 필드가 존재할 때만 두 개의 필드에 값이 필요할 수도 있습니다. 이런 규칙을 추가하는 작업이 어렵게 느껴질 필요는 없습니다. 먼저 절대 변하지 않는 **고정 규칙(static rules)**으로 Validator 인스턴스를 생성해보겠습니다:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), [
'email' => ['required', 'email'],
'games' => ['required', 'integer', 'min:0'],
]);우리가 만드는 웹 애플리케이션이 게임 수집가들을 위한 서비스라고 가정해봅시다. 가입하려는 수집가가 보유한 게임이 100개를 초과한다면, 왜 그렇게 많은 게임을 소장하고 있는지 이유를 입력받고 싶습니다. 예를 들어 중고 게임 판매점을 운영 중이거나, 단순히 수집 자체를 즐기는 경우일 수 있겠죠. 이런 조건부 요구사항을 추가하려면 Validator 인스턴스의 sometimes 메서드를 사용하면 됩니다.
use Illuminate\Support\Fluent;
$validator->sometimes('reason', ['required', 'max:500'], function (Fluent $input) {
return $input->games >= 100;
});sometimes 메서드의 첫 번째 인자는 조건부로 검사할 필드의 이름입니다. 두 번째 인자는 추가하고자 하는 규칙 목록입니다. 세 번째 인자로 전달한 클로저가 true를 반환하면 해당 규칙이 적용됩니다. 이 메서드를 사용하면 복잡한 조건부 유효성 검사도 손쉽게 구현할 수 있습니다. 여러 필드에 대해 한 번에 조건부 검사를 추가할 수도 있습니다:
$validator->sometimes(['reason', 'cost'], 'required', function (Fluent $input) {
return $input->games >= 100;
});NOTE
클로저에 전달되는 $input 매개변수는 Illuminate\Support\Fluent의 인스턴스이며, 검사 대상이 되는 입력값과 파일에 접근하는 데 사용할 수 있습니다.
복잡한 조건부 배열 유효성 검사
때로는 인덱스를 알 수 없는 중첩 배열 안에서, 같은 배열 내의 다른 필드 값을 기준으로 유효성 검사를 하고 싶을 수 있습니다. 이런 경우 클로저가 두 번째 인자를 받도록 하면, 현재 검사 중인 배열의 개별 항목을 전달받을 수 있습니다:
$input = [
'channels' => [
[
'type' => 'email',
'address' => 'abigail@example.com',
],
[
'type' => 'url',
'address' => 'https://example.com',
],
],
];
$validator->sometimes('channels.*.address', 'email', function (Fluent $input, Fluent $item) {
return $item->type === 'email';
});
$validator->sometimes('channels.*.address', 'url', function (Fluent $input, Fluent $item) {
return $item->type !== 'email';
});$input 매개변수와 마찬가지로, $item 매개변수 역시 검사 대상 속성 데이터가 배열인 경우에는 Illuminate\Support\Fluent의 인스턴스가 되며, 그렇지 않은 경우에는 문자열이 됩니다.
유효성 검사 - 배열 유효성 검사
배열 유효성 검사
array 유효성 검사 규칙 문서에서 다룬 것처럼, array 규칙에는 허용할 배열 키 목록을 지정할 수 있습니다. 배열 안에 지정하지 않은 키가 하나라도 포함되어 있으면 유효성 검사는 실패합니다:
use Illuminate\Support\Facades\Validator;
$input = [
'user' => [
'name' => 'Taylor Otwell',
'username' => 'taylorotwell',
'admin' => true,
],
];
Validator::make($input, [
'user' => ['array:name,username'],
]);일반적으로는 배열에 허용되는 키를 항상 명시적으로 지정하는 것이 좋습니다. 그렇지 않으면 validator의 validate, validated 메서드가 실제로 다른 중첩 배열 규칙으로 검증하지 않은 키까지 포함해서, 배열 전체와 모든 키를 반환하게 됩니다.
NOTE
예를 들어 회원가입 폼에서 user.name, user.email만 검증하도록 규칙을 작성했는데 array 규칙에서 허용 키를 지정하지 않았다면, 사용자가 임의로 user.is_admin 같은 값을 요청에 끼워 넣어도 validated() 결과에 그대로 포함될 수 있습니다. 민감한 필드를 다루는 배열이라면 반드시 허용 키를 명시하세요.
중첩 배열 입력값 검증
중첩된 배열 형태의 폼 입력 필드를 검증하는 일이 어렵게 느껴질 필요는 없습니다. "점(dot) 표기법"을 사용하면 배열 안의 속성도 손쉽게 검증할 수 있습니다. 예를 들어 HTTP 요청에 photos[profile] 필드가 포함되어 있다면 다음과 같이 검증할 수 있습니다:
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($request->all(), [
'photos.profile' => ['required', 'image'],
]);배열의 각 요소를 검증할 수도 있습니다. 예를 들어 배열 입력 필드 안에 있는 각각의 이메일이 유일한 값인지 검증하려면 다음과 같이 작성합니다:
$validator = Validator::make($request->all(), [
'users.*.email' => ['email', 'unique:users'],
'users.*.first_name' => ['required_with:users.*.last_name'],
]);마찬가지로, 언어 파일에서 특정 속성에 대한 커스텀 유효성 검사 메시지를 지정할 때도 * 문자를 사용할 수 있습니다. 덕분에 배열 기반 필드 전체에 하나의 유효성 검사 메시지를 손쉽게 적용할 수 있습니다:
'custom' => [
'users.*.email' => [
'unique' => '각 사용자는 고유한 이메일 주소를 가져야 합니다.',
]
],중첩된 배열 데이터에 접근하기
경우에 따라 속성에 유효성 검사 규칙을 지정할 때, 해당 중첩 배열 요소의 값을 참조해야 할 수도 있습니다. 이럴 때는 Rule::forEach 메서드를 사용하면 됩니다. forEach 메서드는 클로저를 인수로 받으며, 이 클로저는 검증 대상 배열 속성의 각 반복(iteration)마다 호출됩니다. 클로저는 해당 요소의 값과, 점 표기법으로 완전히 확장된 속성 이름을 인수로 전달받습니다. 클로저는 해당 배열 요소에 적용할 규칙 배열을 반환해야 합니다:
use App\Rules\HasPermission;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
$validator = Validator::make($request->all(), [
'companies.*.id' => Rule::forEach(function (string|null $value, string $attribute) {
return [
Rule::exists(Company::class, 'id'),
new HasPermission('manage-company', $value),
];
}),
]);오류 메시지의 인덱스와 위치
배열을 검증할 때, 유효성 검사에 실패한 항목이 배열 내 몇 번째 위치에 있는지를 오류 메시지에 표시하고 싶을 수 있습니다. 이를 위해 커스텀 유효성 검사 메시지 안에 :index(0부터 시작), :position(1부터 시작), :ordinal-position(1st부터 시작하는 서수) 플레이스홀더를 사용할 수 있습니다:
use Illuminate\Support\Facades\Validator;
$input = [
'photos' => [
[
'name' => 'BeachVacation.jpg',
'description' => 'A photo of my beach vacation!',
],
[
'name' => 'GrandCanyon.jpg',
'description' => '',
],
],
];
Validator::validate($input, [
'photos.*.description' => ['required'],
], [
'photos.*.description.required' => ':position번째 사진에 대한 설명을 입력해 주세요.',
]);위 예시에서는 유효성 검사가 실패하며, 사용자에게는 "2번째 사진에 대한 설명을 입력해 주세요."라는 오류 메시지가 표시됩니다.
필요하다면 second-index, second-position, third-index, third-position 등을 사용해 더 깊이 중첩된 배열의 인덱스나 위치도 참조할 수 있습니다.
'photos.*.attributes.*.string' => ':second-position번째 속성이 사진에 유효하지 않습니다.',파일 유효성 검사
라라벨은 업로드된 파일을 검증하기 위한 다양한 유효성 검사 규칙을 제공합니다. mimes, image, min, max 등의 규칙을 개별적으로 지정할 수도 있지만, 라라벨은 좀 더 편리하게 사용할 수 있는 파일 유효성 검사 규칙 빌더도 함께 제공합니다.
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\File;
Validator::validate($input, [
'attachment' => [
'required',
File::types(['mp3', 'wav'])
->min(1024)
->max(12 * 1024),
],
]);파일 타입 검증하기
types 메서드를 호출할 때 확장자만 지정하면 되지만, 실제로 이 메서드는 파일의 내용을 읽어서 MIME 타입을 추측한 뒤 그것을 기준으로 검증을 수행합니다. 즉, 단순히 파일 확장자만 확인하는 것이 아니라 실제 파일 내용을 분석합니다.
MIME 타입과 그에 대응하는 확장자의 전체 목록은 아래 링크에서 확인할 수 있습니다.
https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
파일 크기 검증하기
편의를 위해 최소/최대 파일 크기는 단위 접미사가 붙은 문자열로 지정할 수 있습니다. kb, mb, gb, tb 접미사를 사용할 수 있습니다.
File::types(['mp3', 'wav'])
->min('1kb')
->max('10mb');이미지 파일 검증하기
사용자가 업로드한 이미지를 받는 경우, File 규칙의 image 생성자 메서드를 사용해서 검증 대상 파일이 이미지(jpg, jpeg, png, bmp, gif, webp)인지 확인할 수 있습니다.
추가로 dimensions 규칙을 사용하면 이미지의 가로/세로 크기를 제한할 수 있습니다.
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\File;
Validator::validate($input, [
'photo' => [
'required',
File::image()
->min(1024)
->max(12 * 1024)
->dimensions(Rule::dimensions()->maxWidth(1000)->maxHeight(500)),
],
]);NOTE
이미지 크기(dimensions) 검증에 대한 더 자세한 내용은 dimensions 규칙 문서를 참고하세요.
WARNING
image 규칙은 XSS 취약점 가능성 때문에 기본적으로 SVG 파일을 허용하지 않습니다. SVG 파일을 허용해야 한다면 image 규칙에 allowSvg: true를 전달하세요: File::image(allowSvg: true).
이미지 크기(Dimensions) 검증하기
업로드된 이미지의 가로/세로 크기도 검증할 수 있습니다. 예를 들어, 업로드된 이미지가 최소 가로 1000픽셀, 세로 500픽셀 이상인지 검증하려면 dimensions 규칙을 사용하면 됩니다.
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\File;
File::image()->dimensions(
Rule::dimensions()
->maxWidth(1000)
->maxHeight(500)
);NOTE
이미지 크기(dimensions) 검증에 대한 더 자세한 내용은 dimensions 규칙 문서를 참고하세요.
유효성 검사
비밀번호 유효성 검사
애플리케이션의 비밀번호가 충분한 복잡도를 갖도록 하려면 Laravel이 제공하는 Password 규칙 객체를 사용할 수 있습니다:
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\Password;
$validator = Validator::make($request->all(), [
'password' => ['required', 'confirmed', Password::min(8)],
]);Password 규칙 객체를 사용하면 최소 하나의 문자, 숫자, 특수문자, 대소문자 혼합 등 애플리케이션에서 요구하는 비밀번호 복잡도 규칙을 손쉽게 지정할 수 있습니다:
// 최소 8자 이상 요구...
Password::min(8);
// 최대 256자까지 허용...
Password::min(16)->max(256);
// 최소 하나 이상의 문자 요구...
Password::min(8)->letters();
// 대문자와 소문자를 각각 최소 하나 이상 요구...
Password::min(8)->mixedCase();
// 최소 하나 이상의 숫자 요구...
Password::min(8)->numbers();
// 최소 하나 이상의 특수문자 요구...
Password::min(8)->symbols();또한 uncompromised 메서드를 사용하면 해당 비밀번호가 공개적으로 유출된 데이터 침해 사고에 노출된 적이 있는지 확인할 수 있습니다:
Password::min(8)->uncompromised();내부적으로 Password 규칙 객체는 k-익명성(k-Anonymity) 모델을 활용해 haveibeenpwned.com 서비스와 통신하며, 이 과정에서 사용자의 개인정보나 보안을 침해하지 않고도 비밀번호 유출 여부를 판별합니다.
NOTE
haveibeenpwned.com 서비스는 실제 비밀번호 전체가 아니라, 비밀번호를 해싱한 값의 앞부분 일부만 전송받아 대조하는 방식으로 동작합니다. 따라서 실제 비밀번호가 외부로 노출될 위험은 없습니다.
기본적으로 데이터 유출 목록에 비밀번호가 단 한 번이라도 발견되면 "유출된 것"으로 간주됩니다. uncompromised 메서드의 첫 번째 인자로 이 기준값을 직접 지정할 수도 있습니다:
// 동일한 유출 데이터에서 3회 미만으로 발견된 경우만 통과...
Password::min(8)->uncompromised(3);물론 위 예시의 모든 메서드는 체이닝하여 함께 사용할 수 있습니다:
Password::min(8)
->max(256)
->letters()
->mixedCase()
->numbers()
->symbols()
->uncompromised();toPasswordRulesString 메서드를 사용하면 Password 규칙 객체를 HTML의 passwordrules 속성에 사용할 수 있는 문자열로 변환할 수 있습니다:
<input
type="password"
name="password"
autocomplete="new-password"
passwordrules="{{ Password::defaults()->toPasswordRulesString() }}"
/>기본 비밀번호 규칙 정의하기
애플리케이션 전체에서 사용할 비밀번호 유효성 검사 규칙을 한 곳에서 관리하면 편리한 경우가 많습니다. Password::defaults 메서드를 사용하면 클로저를 통해 이를 쉽게 설정할 수 있습니다. defaults 메서드에 전달하는 클로저는 기본 Password 규칙 설정을 반환해야 하며, 보통 서비스 프로바이더의 boot 메서드 안에서 호출합니다:
use Illuminate\Validation\Rules\Password;
/**
* 애플리케이션 서비스를 부트스트랩합니다.
*/
public function boot(): void
{
Password::defaults(function () {
$rule = Password::min(8);
return $this->app->isProduction()
? $rule->mixedCase()->uncompromised()
: $rule;
});
}이렇게 설정해두면, 유효성 검사 시 defaults 메서드를 인자 없이 호출하는 것만으로 기본 규칙을 그대로 적용할 수 있습니다:
'password' => ['required', Password::defaults()],경우에 따라 기본 비밀번호 규칙에 추가적인 유효성 검사 규칙을 덧붙이고 싶을 수도 있습니다. 이럴 때는 rules 메서드를 사용하면 됩니다:
use App\Rules\ZxcvbnRule;
Password::defaults(function () {
$rule = Password::min(8)->rules([new ZxcvbnRule]);
// ...
});NOTE
예시에 사용된 ZxcvbnRule은 Laravel에 포함된 규칙이 아니며, zxcvbn-php 같은 서드파티 패키지를 활용해 직접 구현하는 커스텀 규칙의 예시입니다. 실제 사용 시에는 상황에 맞는 패키지나 로직을 선택해 적용하세요.
유효성 검사
커스텀 유효성 검사 규칙
규칙 객체 사용하기
Laravel은 다양한 유효성 검사 규칙을 기본으로 제공하지만, 필요에 따라 직접 규칙을 정의할 수도 있습니다. 커스텀 유효성 검사 규칙을 등록하는 방법 중 하나는 규칙 객체를 사용하는 것입니다. 새로운 규칙 객체를 생성하려면 make:rule Artisan 명령어를 사용하면 됩니다. 문자열이 모두 대문자인지 검사하는 규칙을 예시로 만들어 보겠습니다. Laravel은 새로 생성된 규칙을 app/Rules 디렉터리에 위치시킵니다. 이 디렉터리가 존재하지 않는다면, 규칙 생성 명령어를 실행할 때 Laravel이 자동으로 만들어 줍니다:
php artisan make:rule Uppercase규칙을 생성했다면, 이제 동작을 정의할 차례입니다. 규칙 객체는 validate라는 단 하나의 메서드를 가지고 있습니다. 이 메서드는 속성(attribute)의 이름, 값, 그리고 검증에 실패했을 때 호출할 콜백을 인자로 받습니다:
<?php
namespace App\Rules;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class Uppercase implements ValidationRule
{
/**
* 유효성 검사 규칙을 실행합니다.
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (strtoupper($value) !== $value) {
$fail('The :attribute must be uppercase.');
}
}
}규칙을 정의했다면, 다른 유효성 검사 규칙과 함께 규칙 객체의 인스턴스를 전달하여 validator에 연결할 수 있습니다:
use App\Rules\Uppercase;
$request->validate([
'name' => ['required', 'string', new Uppercase],
]);유효성 검사 메시지 번역하기
$fail 클로저에 문자 그대로의 에러 메시지를 전달하는 대신, 번역 문자열 키를 전달하여 Laravel이 해당 에러 메시지를 번역하도록 지시할 수도 있습니다:
if (strtoupper($value) !== $value) {
$fail('validation.uppercase')->translate();
}필요하다면 translate 메서드의 첫 번째 인자로 치환할 플레이스홀더 값을, 두 번째 인자로 원하는 언어를 전달할 수 있습니다:
$fail('validation.location')->translate([
'value' => $this->value,
], 'fr');추가 데이터에 접근하기
커스텀 유효성 검사 규칙 클래스에서 검증 중인 다른 모든 데이터에 접근해야 한다면, 해당 규칙 클래스는 Illuminate\Contracts\Validation\DataAwareRule 인터페이스를 구현할 수 있습니다. 이 인터페이스는 setData 메서드를 정의하도록 요구합니다. 이 메서드는 검증이 진행되기 전에 Laravel이 검증 대상 데이터 전체를 담아 자동으로 호출해 줍니다:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidationRule;
class Uppercase implements DataAwareRule, ValidationRule
{
/**
* 검증 대상 데이터 전체.
*
* @var array<string, mixed>
*/
protected $data = [];
// ...
/**
* 검증 대상 데이터를 설정합니다.
*
* @param array<string, mixed> $data
*/
public function setData(array $data): static
{
$this->data = $data;
return $this;
}
}또는 검증을 수행하는 validator 인스턴스 자체에 접근해야 하는 경우, ValidatorAwareRule 인터페이스를 구현할 수 있습니다:
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;
use Illuminate\Validation\Validator;
class Uppercase implements ValidationRule, ValidatorAwareRule
{
/**
* validator 인스턴스.
*
* @var \Illuminate\Validation\Validator
*/
protected $validator;
// ...
/**
* 현재 validator를 설정합니다.
*/
public function setValidator(Validator $validator): static
{
$this->validator = $validator;
return $this;
}
}클로저 사용하기
애플리케이션 전체에서 딱 한 번만 필요한 커스텀 규칙이라면, 별도의 규칙 객체를 만들지 않고 클로저를 사용할 수도 있습니다. 이 클로저는 속성 이름, 속성 값, 그리고 검증 실패 시 호출해야 하는 $fail 콜백을 인자로 받습니다:
use Illuminate\Support\Facades\Validator;
use Closure;
$validator = Validator::make($request->all(), [
'title' => [
'required',
'max:255',
function (string $attribute, mixed $value, Closure $fail) {
if ($value === 'foo') {
$fail("The {$attribute} is invalid.");
}
},
],
]);암묵적 규칙(Implicit Rules)
기본적으로 검증 대상 속성이 존재하지 않거나 빈 문자열인 경우, 커스텀 규칙을 포함한 일반적인 유효성 검사 규칙은 실행되지 않습니다. 예를 들어 unique 규칙은 빈 문자열에 대해서는 실행되지 않습니다:
use Illuminate\Support\Facades\Validator;
$rules = ['name' => ['unique:users,name']];
$input = ['name' => ''];
Validator::make($input, $rules)->passes(); // true속성 값이 비어 있을 때도 커스텀 규칙이 실행되도록 하려면, 해당 규칙이 이 속성이 필수(required)임을 암묵적으로 내포하고 있어야 합니다. 새로운 암묵적 규칙 객체를 빠르게 생성하려면, make:rule Artisan 명령어에 --implicit 옵션을 추가하면 됩니다:
php artisan make:rule Uppercase --implicitWARNING
"암묵적(implicit)" 규칙은 단지 해당 속성이 필수임을 _암시_할 뿐입니다. 실제로 값이 없거나 빈 속성을 유효하지 않은 것으로 처리할지는 여러분이 직접 로직으로 구현해야 합니다.