Laravelなしで使う!Illuminate/Validationを単体で使用する方法

こんにちは、コバヤシです。
ある案件で、素のPHPにバリデーションを入れる必要があり、以前ブログで紹介した「validation」を使おうとしたところ、メンテナンスされていないようでした。。

tech.arms-soft.co.jp

そこで、今回はLaravelで使用されている「illuminate/validation」を使用してみました。

illuminate/validation

「illuminate/validation」とは、Laravelで使用されているバリデーション機能を提供するPHPライブラリです。Laravelで利用されている多様なバリデーションルールをそのまま活用でき、スタンドアローンのPHPプロジェクトでも利用可能です。

github.com

インストール

Composerでインストールを行います。

composer require illuminate/validation

使い方

基本的に、Laravelのバリデーションと同じ使い方です。

<?php
require __DIR__ . '/vendor/autoload.php';
  
use Illuminate\Validation\Factory as ValidatorFactory;
use Illuminate\Translation\ArrayLoader;
use Illuminate\Translation\Translator;
  
$translator = new Translator(new ArrayLoader(), 'ja');
$validatorFactory = new ValidatorFactory($translator);
  
// データの定義
$data = [
    'name' => '山田太郎',
    'email' => 'hoge@example.hoge',
    'age' => 17,
];
  
// バリデーションルールの定義
$rules = [
    'name' => 'required|string|max:10',
    'email' => 'required|email',
    'age' => 'required|integer|min:18',
];
  
// メッセージの定義
$messages = [
    'name.required' => '名前は必須です。',
    'name.string' => '名前は文字列である必要があります。',
    'name.max' => '名前は10文字以下である必要があります。',
    'email.required' => 'メールアドレスは必須です。',
    'email.email' => 'メールアドレスの形式が正しくありません。',
    'age.min' => '年齢は18歳以上である必要があります。',
    'age.integer' => '年齢は整数である必要があります。',
];
 
// フィールド名
$attributes = [
    'email' => 'メールアドレス',
    'name' => '名前',
    'age' => '年齢',
];
  
// バリデータの作成
$validator = $validatorFactory->make($data, $rules, $messages, $attributes);
  
// バリデーションの実行
if ($validator->fails()) {
    // バリデーションエラーの表示
    $errors = $validator->errors();
    foreach ($errors->all() as $message) {
        echo $message . PHP_EOL;
    }
} else {
    echo "すべてOK!!!" . PHP_EOL;
}

バリデーションも、ほぼ同じものを使うことが出来ます。
(uniqueとかはモデルも絡むのでそのままでは使えないです)

デフォルトのメッセージを設定する

Laravelと同様に、デフォルトのエラーメッセージを設定できます。
任意の場所に「ja」ディレクトリを作り、その中に validation.php 言語ファイルを作成し、FileLoaderクラスにそのパスを指定します。
形式はLaravelと同じなので、そのまま流用できます。

/lang/ja/validation.php

<?php
  
return [
    'required' => ':attributeは必須です。',
    'string' => ':attributeには、文字を指定してください。',
    'integer' => ':attributeには、整数を指定してください。',
    'email' => ':attributeには正しい形式のメールアドレスを指定してください。',
    'max'                  => [
        'numeric' => ':attributeには、:max以下の数字を指定してください。',
        'file'    => ':attributeには、:max KB以下のファイルを指定してください。',
        'string'  => ':attributeは、:max文字以下にしてください。',
        'array'   => ':attributeの項目は、:max個以下にしてください。',
    ],
    'min' => [
      'array' => ':attributeには:min個以上の要素を持つ配列を指定してください。',
      'file' => ':attributeには:min KB以上のファイルを指定してください。',
      'numeric' => ':attributeには:min以上の数値を指定してください。',
      'string' => ':attributeには:min文字以上の文字列を指定してください。',
    ],
];
<?php
require __DIR__ . '/vendor/autoload.php';
  
use Illuminate\Filesystem\Filesystem;
use Illuminate\Translation\FileLoader;
use Illuminate\Validation\Factory as ValidatorFactory;
use Illuminate\Translation\Translator;
  
$loader = new FileLoader(new Filesystem(), __DIR__ . '/lang'); // 言語ファイルがあるディレクトリを指定
$translator = new Translator($loader, 'ja'); // Translatorのローダーに上記ローダーを指定する
$validatorFactory = new ValidatorFactory($translator);
  
// データの定義
$data = [
    'name' => '山田太郎',
    'email' => 'hoge@example.hoge',
    'age' => 17,
];
  
// バリデーションルールの定義
$rules = [
    'name' => 'required|string|max:10',
    'email' => 'required|email',
    'age' => 'required|integer|min:18',
];
  
// フィールド名
$attributes = [
    'name' => '名前',
    'email' => 'メールアドレス',
    'age' => '年齢',
];
  
// バリデータの作成
$validator = $validatorFactory->make($data, $rules, [], $attributes);
  
// バリデーションの実行
if ($validator->fails()) {
    // バリデーションエラーの表示
    $errors = $validator->errors();
    foreach ($errors->all() as $message) {
        echo $message . PHP_EOL;
    }
} else {
    echo "すべてOK!!!" . PHP_EOL;
}

カスタムバリデーションの作成

もちろんカスタムバリデーションも作成できます。

カスタムルールを作成する方法

<?php
$validatorFactory->extend('odd_number', function ($attribute, $value, $parameters, $validator) {
    return $value % 2 !== 0;
}, ':attribute は奇数を入力してください。');
  
// バリデーションルールの定義
$rules = [
    'name' => 'required|string|max:10',
    'email' => 'required|email',
    'age' => 'required|integer|min:18|odd_number',
];

extendメソッドを使用し、クロージャを用いてカスタムバリデーションルールを追加します。
このあたりもLaravelと変わらないですね。

バリデーションルールクラスを作成する方法

もちろん、バリデーションルールクラスを作成する方法でも可能です。

/rules/OddNumber.php

<?php
  
namespace App\Rules;
  
use Illuminate\Contracts\Validation\ValidationRule;
  
class OddNumber implements ValidationRule
{
    /**
     * 奇数かどうかを検証する
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @param  \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString  $fail
     * @return void
     */
    public function validate(string $attribute, mixed $value, \Closure $fail): void
    {
        if ($value % 2 === 0) {
            $fail(':attribute は奇数を入力してください。');
        }
    }
}
<?php
$rules = [
    'name' => ['required', 'string', 'max:10'],
    'email' => ['required', 'email'],
    'age' => ['required', 'integer', 'min:18', new OddNumber],
];

バリデーションルールを作成し、ルールに設定します。

まとめ

illuminate/validationを使うと、Laravelのバリデーション機能をそのままスタンドアロンのPHPプロジェクトでも利用できました。いつも使っている機能なので学習コストもなく、そのまま使用できて便利ですね。
今後は素のPHPでバリデーションが必要になった場合はilluminate/validationを利用していきたいと思います。