NoraLib Validation API Documentation

ベストプラクティス

NoraLib Validationを効果的に使うための推奨事項です。

設計原則

単一責任の原則

各バリデーションルールは1つの責任のみを持つべきです:

良い例:

$validator
    ->notEmpty()           // 空チェック
    ->length(min: 8)       // 長さチェック
    ->passwordStrength();  // 強度チェック

悪い例:

// 1つのカスタムルールで全てをチェック(保守性が低い)
$validator->custom(function($value) {
    return !empty($value) && 
           strlen($value) >= 8 && 
           preg_match('/[A-Z]/', $value) &&
           preg_match('/[0-9]/', $value);
}, '複雑なエラーメッセージ');

再利用可能なポリシー

よく使うバリデーションはポリシーとして定義します:

class ValidationPolicies
{
    public static function setupStandardPolicies(Validator $validator): void
    {
        // メールアドレス
        $validator->setPolicy('email', [
            new NotEmptyRule(),
            new ValidEmailRule(),
        ]);

        // 強力なパスワード
        $validator->setPolicy('strong_password', [
            new NotEmptyRule(),
            new LengthRule(12, 64),
            new PasswordComplexityRule(4),
            new PasswordNoCommonWordRule(),
        ]);
    }
}

// 使用
$validator = new Validator();
ValidationPolicies::setupStandardPolicies($validator);
$passwordValidator = $validator->policy('strong_password');

エラーハンドリング

フォーム全体のバリデーション

use NoraLib\Validation\Exception\ValidationalError;
use NoraLib\Validation\Rule\Exception\ExceptionGroup;

function validateUserForm(array $data): array
{
    $validator = new Validator();
    $formValidator = $validator->array([
        'username' => $validator->policy('username'),
        'email' => $validator->policy('email'),
        'password' => $validator->policy('strong_password'),
    ]);

    try {
        $formValidator->assert($data);
        return ['success' => true];
    } catch (ExceptionGroup $e) {
        $error = ValidationalError::createFromValidator($e);
        return [
            'success' => false,
            'errors' => $error->buildPayload(),
        ];
    }
}

パフォーマンス

早期リターン

バリデーションは短絡評価されます。最も失敗しやすいルールを先に配置します:

// 良い例:空チェックを最初に
$validator
    ->notEmpty()           // 最も失敗しやすい
    ->length(min: 8)
    ->passwordStrength();  // 最も重い処理

セキュリティ

パスワードバリデーション

常に複数の側面をチェックします:

$validator->setPolicy('secure_password', [
    new NotEmptyRule(),
    new LengthRule(12, 128),           // 最小12文字
    new PasswordComplexityRule(4),     // 全4種類の文字
    new PasswordNoCommonWordRule(),    // 一般的なパスワードを除外
]);

入力サニタイゼーション

バリデーションは検証のみを行います。サニタイゼーションは別途行ってください:

// 良い例
$cleanEmail = filter_var($email, FILTER_SANITIZE_EMAIL);
if ($validator->validEmail()->validate($cleanEmail)) {
    // 使用
}

テスト

バリデーションルールのテスト

use PHPUnit\Framework\TestCase;

class CustomRuleTest extends TestCase
{
    public function testEvenNumberValidation(): void
    {
        $rule = new EvenNumberRule();
        
        $this->assertTrue($rule->validate(2));
        $this->assertTrue($rule->validate(100));
        $this->assertFalse($rule->validate(1));
        $this->assertFalse($rule->validate(99));
        $this->assertTrue($rule->validate(null)); // 空は許可
    }

    public function testEvenNumberException(): void
    {
        $rule = new EvenNumberRule();
        
        $this->expectException(EvenNumberException::class);
        $rule->assert(3);
    }
}

まとめ

  • 単一責任 : 1ルール1責任
  • ポリシー : 再利用可能な組み合わせを定義
  • 早期リターン : 失敗しやすいルールを先に
  • セキュリティ : 複数のチェックを組み合わせる
  • テスト : カスタムルールは必ずテストする

Search results