ApnaPHP

Documentation

Validation

ApnaPHP provides a robust and easy-to-use validation system to ensure your application receives clean and valid data. You can validate incoming HTTP requests, form submissions, and any other data.

1. Basic Validation

The validate() helper function is the primary way to validate data in ApnaPHP. It takes the data to be validated and an array of rules.

<?php

use ApnaPHP\Routing\Request;
use ApnaPHP\Routing\Response;
use ApnaPHP\Support\Validation;

function POST(Request $request): Response
{
    try {
        $validatedData = validate($request->all(), [
            'name' => 'required|min:3|max:255',
            'email' => 'required|email',
            'password' => 'required|min:8|confirmed',
        ]);

        // Data is valid, proceed with creating user
        // $user = User::create($validatedData);

        return Response::json(['message' => 'User created successfully!', 'data' => $validatedData], 201);

    } catch (ValidationException $e) {
        // Validation failed, return JSON response with errors
        return Response::json(['errors' => $e->errors()], 422);
    }
}

Error Handling

When validation fails, a ValidationException is thrown. You should catch this exception and return an appropriate response, typically a JSON response with a 422 Unprocessable Entity status code for APIs, or redirect back with errors for web forms.

2. Built-in Validation Rules

ApnaPHP comes with a comprehensive set of built-in validation rules based on the actual framework implementation.

String & Text Rules

  • required: The field must be present and not empty.
  • min:value: The field must have a minimum length (for strings) or value (for numbers).
  • max:value: The field may not be greater than the specified length (for strings) or value (for numbers).
  • alpha: The field must contain only letters.
  • alpha_num: The field must contain only letters and numbers.
  • alpha_dash: The field may contain letters, numbers, dashes, and underscores.
  • regex:pattern: The field must match the given regular expression pattern.
  • min_length:value: The field must be at least the specified number of characters.
  • max_length:value: The field may not be greater than the specified number of characters.
  • size:value: The field must be exactly the specified number of characters.
  • between:min,max: The field must be between the given minimum and maximum length.

Numeric Rules

  • numeric: The field must be a number.
  • integer: The field must be an integer.
  • float: The field must be a float.

Email & URL Rules

  • email: The field must be a valid email address.
  • url: The field must be a valid URL.

Date Rules

  • date: The field must be a valid date.
  • before:date: The field must be a date before the given date.
  • after:date: The field must be a date after the given date.

Comparison Rules

  • same:field: The field must match the given field.
  • different:field: The field must be different from the given field.
  • confirmed: The field must have a matching confirmation field (e.g., password_confirmation).

Selection Rules

  • in:value1,value2,...: The field must be included in the given list of values.
  • not_in:value1,value2,...: The field must not be included in the given list of values.

File Upload Rules

  • file: The field must be a successfully uploaded file.
  • image: The file must be an image (JPEG, PNG, GIF, WebP, SVG).
  • mimes:type1,type2,...: The file must have a MIME type corresponding to one of the listed types.
  • max_file_size:value: The file size must not be greater than the specified value in kilobytes.

Nullable Rules

  • nullable: The field may be null or empty. If nullable and empty, all other validation rules are skipped.

3. Real-World Examples

User Registration

$validated = validate($request->all(), [
    'name' => 'required|min:3|max:255',
    'email' => 'required|email',
    'password' => 'required|min:8|confirmed', // Requires a 'password_confirmation' field
    'phone' => 'nullable|regex:/^[0-9]{10}$/',
    'age' => 'required|integer|min:18|max:120',
    'terms' => 'required|in:yes,on,1,true'
]);

Product Creation

$validated = validate($request->all(), [
    'name' => 'required|max:255',
    'slug' => 'required|alpha_dash|unique:products,slug',
    'description' => 'nullable|max:1000',
    'price' => 'required|numeric|min:0',
    'category_id' => 'required|integer',
    'image' => 'required|image|max_file_size:2048|mimes:image/jpeg,image/png,image/gif,image/svg+xml,image/webp', // Max 2MB
    'tags' => 'nullable|alpha_dash',
]);

Profile Update

$userId = auth()->id(); // Get current user's ID
$validated = validate($request->all(), [
    'name' => 'required|min:3|max:255',
    'email' => 'required|email',
    'bio' => 'nullable|max:500',
    'avatar' => 'nullable|image|max_file_size:1024', // Max 1MB
]);

4. Custom Error Messages

You can customize the validation error messages by passing a third argument to the validate() helper.

try {
    $validatedData = validate($request->all(),
        [
            'email' => 'required|email',
            'password' => 'required|min:8',
        ],
        [
            'email.required' => 'Email address is mandatory.',
            'email.email' => 'Please enter a valid email format.',
            'password.required' => 'Password cannot be empty.',
            'password.min' => 'Password must be at least :min characters long.',
        ]
    );
} catch (ValidationException $e) {
    return Response::json(['errors' => $e->errors()], 422);
}

5. Validation Helper Functions

ApnaPHP provides several helper functions for common validation tasks:

Email Validation

if (isValidEmail($email)) {
    // Email is valid
}

URL Validation

if (isValidUrl($url)) {
    // URL is valid
}

Phone Validation

if (isValidPhone($phone)) {
    // Phone number is valid
}

Credit Card Validation

if (isValidCreditCard($cardNumber)) {
    // Credit card number is valid (Luhn algorithm)
}

UUID Validation

if (isValidUuid($uuid)) {
    // UUID is valid
}

6. Form Validation Example

Here's a complete example of form validation with error display:

<?php
// app/register/page.apna.php

use ApnaPHP\Routing\Request;
use ApnaPHP\Routing\Response;

function POST(Request $request): Response
{
    try {
        $validated = validate($request->all(), [
            'name' => 'required|min:3|max:255',
            'email' => 'required|email',
            'password' => 'required|min:8|confirmed',
            'phone' => 'nullable|regex:/^[0-9]{10}$/',
            'age' => 'required|integer|min:18|max:120',
            'terms' => 'required|in:yes,on,1,true'
        ]);

        // Create user
        $user = User::create($validated);
        
        return redirect('/login')->withSuccess('Account created successfully!');

    } catch (ValidationException $e) {
        return redirect('/register')->withErrors($e->errors())->withInput();
    }
}

// Get validation errors and old input
$errors = getFlash('errors', []);
$oldInput = getFlash('old_input', []);
?>

<!DOCTYPE html>
<html>
<head>
    <title>User Registration</title>
</head>
<body>
    <form method="POST">
        <div>
            <label>Name:</label>
            <input type="text" name="name" value="<?= old('name') ?>">
            <?php if (isset($errors['name'])): ?>
                <span class="error"><?= $errors['name'][0] ?></span>
            <?php endif; ?>
        </div>
        
        <div>
            <label>Email:</label>
            <input type="email" name="email" value="<?= old('email') ?>">
            <?php if (isset($errors['email'])): ?>
                <span class="error"><?= $errors['email'][0] ?></span>
            <?php endif; ?>
        </div>
        
        <div>
            <label>Password:</label>
            <input type="password" name="password">
            <?php if (isset($errors['password'])): ?>
                <span class="error"><?= $errors['password'][0] ?></span>
            <?php endif; ?>
        </div>
        
        <div>
            <label>Confirm Password:</label>
            <input type="password" name="password_confirmation">
        </div>
        
        <div>
            <label>Phone (optional):</label>
            <input type="text" name="phone" value="<?= old('phone') ?>">
            <?php if (isset($errors['phone'])): ?>
                <span class="error"><?= $errors['phone'][0] ?></span>
            <?php endif; ?>
        </div>
        
        <div>
            <label>Age:</label>
            <input type="number" name="age" value="<?= old('age') ?>">
            <?php if (isset($errors['age'])): ?>
                <span class="error"><?= $errors['age'][0] ?></span>
            <?php endif; ?>
        </div>
        
        <div>
            <label>
                <input type="checkbox" name="terms" value="yes">
                I agree to the terms and conditions
            </label>
            <?php if (isset($errors['terms'])): ?>
                <span class="error"><?= $errors['terms'][0] ?></span>
            <?php endif; ?>
        </div>
        
        <button type="submit">Register</button>
    </form>
</body>
</html>

7. Best Practices

  • Validate Early: Always validate incoming data as early as possible in the request lifecycle.
  • Be Specific: Use the most specific validation rules possible for each field.
  • User-Friendly Messages: Provide clear and helpful error messages to users.
  • Reusable Rules: If you have complex or frequently used validation logic, consider encapsulating it.
  • File Validation: Always validate file uploads for type, size, and security.
  • Sanitization: Consider sanitizing user input before validation to prevent security issues.