Rakit Validation

Laravelのバリデーションスタイルを採用した、スタンドアロンで使用できるPHP向けバリデーションライブラリ

import { GithubLinkIcon, NpmLinkIcon, WebsiteLinkIcon } from '/components/icons'; import RelatedLinks from '/components/RelatedLinks.astro';

概要

Rakit Validationは、LaravelのバリデーションAPIにインスパイアされた、スタンドアロンで使用できるPHP向けのバリデーションライブラリです。フレームワークに依存せず、あらゆるPHPプロジェクトで簡単にデータ検証を実装できます。

主な特徴

  • Laravelライクな API: Laravel のバリデーションに慣れた開発者にとって親しみやすいAPI設計
  • 配列バリデーション: ドット記法とワイルドカード記法による複雑なデータ構造の検証
  • ファイルアップロード検証: 複数ファイルアップロードにも対応した包括的なファイル検証
  • カスタム属性エイリアス: エラーメッセージで使用される属性名のカスタマイズ
  • カスタムバリデーションメッセージ: 多言語対応を含む柔軟なメッセージカスタマイズ
  • カスタムルール: 独自のバリデーションルールの作成と登録

インストール

Composerを使用してインストール:

composer require "rakit/validation"

基本的な使用方法

シンプルな検証

<?php

use Rakit\Validation\Validator;

$validator = new Validator;

// バリデーションの実行
$validation = $validator->validate($_POST + $_FILES, [
    'name'                  => 'required',
    'email'                 => 'required|email',
    'password'              => 'required|min:6',
    'confirm_password'      => 'required|same:password',
    'avatar'                => 'required|uploaded_file:0,500K,png,jpeg',
    'skills'                => 'array',
    'skills.*.id'           => 'required|numeric',
    'skills.*.percentage'   => 'required|numeric'
]);

if ($validation->fails()) {
    // エラー処理
    $errors = $validation->errors();
    echo "<pre>";
    print_r($errors->firstOfAll());
    echo "</pre>";
} else {
    // バリデーション成功
    echo "Success!";
}

makeメソッドを使用した検証

$validator = new Validator;

// バリデーションオブジェクトの作成
$validation = $validator->make($_POST + $_FILES, [
    'name'     => 'required',
    'email'    => 'required|email',
    'password' => 'required|min:6'
]);

// カスタムメッセージやエイリアスの設定
$validation->setAliases([
    'name'  => '名前',
    'email' => 'メールアドレス',
    'password' => 'パスワード'
]);

// 検証の実行
$validation->validate();

カスタムバリデーションメッセージ

バリデーター全体でのカスタムメッセージ

// コンストラクタで設定
$validator = new Validator([
    'required' => ':attribute は必須項目です',
    'email' => ':attribute は有効なメールアドレスではありません',
    'min' => ':attribute は :min 文字以上必要です'
]);

// または setMessages メソッドを使用
$validator->setMessages([
    'required' => ':attribute は必須項目です',
    'email' => ':email は有効なメールアドレスではありません'
]);

特定の検証でのカスタムメッセージ

$validation = $validator->validate($data, $rules, [
    'required' => ':attribute は必須項目です',
    'email' => ':email は有効なメールアドレスではありません'
]);

特定の属性・ルールでのカスタムメッセージ

$validation = $validator->make($data, [
    'age' => 'required|min:18'
]);

$validation->setMessages([
    'age:min' => '18歳以上の方のみご利用いただけます'
]);

多言語対応(翻訳)

// 翻訳の設定
$validator->setTranslations([
    'and' => 'と',
    'or' => 'または'
]);

// カスタムメッセージの設定
$validator->setMessage('in', ":attribute は :allowed_values のいずれかである必要があります");

// 検証
$validation = $validator->validate($inputs, [
    'number' => 'in:1,2,3'
]);

// エラーメッセージは「Number は '1'、'2'、または '3' のいずれかである必要があります」となる

カスタムルールの作成

クロージャを使用したカスタムルール

$validation = $validator->validate($_POST, [
    'even_number' => [
        'required',
        function ($value) {
            if (!is_numeric($value)) {
                return ":attribute は数値である必要があります";
            }
            if ($value % 2 !== 0) {
                return ":attribute は偶数である必要があります";
            }
            return true;
        }
    ]
]);

クラスベースのカスタムルール

use Rakit\Validation\Rule;

class UniqueRule extends Rule
{
    protected $message = ":attribute :value は既に使用されています";
    protected $fillableParams = ['table', 'column', 'except'];
    protected $pdo;

    public function __construct(PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    public function check($value): bool
    {
        // 必須パラメータの確認
        $this->requireParameters(['table', 'column']);

        $column = $this->parameter('column');
        $table = $this->parameter('table');
        $except = $this->parameter('except');

        if ($except && $except == $value) {
            return true;
        }

        // データベースクエリの実行
        $stmt = $this->pdo->prepare("SELECT COUNT(*) as count FROM `{$table}` WHERE `{$column}` = :value");
        $stmt->bindParam(':value', $value);
        $stmt->execute();
        $data = $stmt->fetch(PDO::FETCH_ASSOC);

        return intval($data['count']) === 0;
    }
}

// カスタムルールの登録
$validator->addValidator('unique', new UniqueRule($pdo));

// 使用例
$validation = $validator->validate($_POST, [
    'email' => 'email|unique:users,email'
]);

配列とネストしたデータの検証

ドット記法

$validation = $validator->validate($data, [
    'user.name' => 'required',
    'user.email' => 'required|email',
    'user.profile.age' => 'required|numeric|min:18'
]);

ワイルドカード記法

// 配列の各要素を検証
$validation = $validator->validate($data, [
    'contacts.*.name' => 'required',
    'contacts.*.email' => 'required|email',
    'contacts.*.phone' => 'required|numeric'
]);

// ネストした配列の検証
$validation = $validator->validate($data, [
    'products.*.variants.*.sku' => 'required',
    'products.*.variants.*.price' => 'required|numeric|min:0'
]);

ファイルアップロードの検証

単一ファイルの検証

$validation = $validator->validate($_FILES, [
    'avatar' => 'required|uploaded_file:0,2M,jpeg,png'
]);

// または個別のルールを使用
$validation = $validator->validate($_FILES, [
    'avatar' => 'required|uploaded_file|max:2M|mimes:jpeg,png'
]);

複数ファイルの検証

// HTML: <input type="file" name="photos[]" multiple>
$validation = $validator->validate($_FILES, [
    'photos.*' => 'uploaded_file:0,2M,jpeg,png'
]);

// 名前付き複数ファイル
// HTML: <input type="file" name="images[profile]">
// HTML: <input type="file" name="images[cover]">
$validation = $validator->validate($_FILES, [
    'images.profile' => 'uploaded_file|max:2M|mimes:jpeg,png',
    'images.cover' => 'uploaded_file|max:5M|mimes:jpeg,png'
]);

エラーハンドリング

エラーメッセージの取得

$validation = $validator->validate($inputs, $rules);
$errors = $validation->errors();

// すべてのエラーメッセージを取得
$allErrors = $errors->all();
// [
//     'メールアドレスは有効なメールアドレスではありません',
//     'パスワードは6文字以上必要です'
// ]

// 各フィールドの最初のエラーを取得
$firstErrors = $errors->firstOfAll();
// [
//     'email' => 'メールアドレスは有効なメールアドレスではありません',
//     'password' => 'パスワードは6文字以上必要です'
// ]

// 特定のフィールドのエラーを取得
$emailError = $errors->first('email');

// エラーの存在確認
if ($errors->has('email')) {
    // emailフィールドにエラーがある
}

// エラー数の取得
$errorCount = $errors->count();

検証済みデータの取得

$validation = $validator->validate([
    'title' => 'Lorem Ipsum',
    'body' => 'Lorem ipsum dolor sit amet',
    'published' => null,
    'invalid' => 'invalid-data'
], [
    'title' => 'required',
    'body' => 'required',
    'published' => 'default:1|required|in:0,1',
    'invalid' => 'required|numeric'
]);

// 検証済みのすべてのデータ(デフォルト値を含む)
$validatedData = $validation->getValidatedData();

// 有効なデータのみ
$validData = $validation->getValidData();

// 無効なデータのみ
$invalidData = $validation->getInvalidData();

利用可能なバリデーションルール

基本的なルール

  • required: 必須フィールド
  • email: 有効なメールアドレス
  • numeric: 数値
  • integer: 整数
  • boolean: 真偽値(true, false, 1, 0, "1", "0")
  • array: 配列
  • json: 有効なJSON文字列

文字列ルール

  • alpha: アルファベットのみ
  • alpha_num: 英数字のみ
  • alpha_dash: 英数字、ダッシュ、アンダースコア
  • alpha_spaces: アルファベットとスペース
  • lowercase: 小文字のみ
  • uppercase: 大文字のみ
  • regex:/pattern/: 正規表現パターンマッチ

サイズルール

  • min:value: 最小値/長さ
  • max:value: 最大値/長さ
  • between:min,max: 範囲内
  • digits:value: 正確な桁数
  • digits_between:min,max: 桁数の範囲

比較ルール

  • same:field: 他のフィールドと同じ値
  • different:field: 他のフィールドと異なる値
  • in:value1,value2,...: 指定された値のいずれか
  • not_in:value1,value2,...: 指定された値以外

日付ルール

  • date: 有効な日付
  • date:format: 特定のフォーマットの日付
  • before:date: 指定日より前
  • after:date: 指定日より後

その他のルール

  • url: 有効なURL
  • ip: 有効なIPアドレス(IPv4またはIPv6)
  • ipv4: 有効なIPv4アドレス
  • ipv6: 有効なIPv6アドレス
  • accepted: 承認を示す値(on, yes, 1, true)
  • nullable: 空の値を許可

関連リンク