sercankara/sanitizer

A comprehensive, framework-agnostic PHP package for data sanitization and validation

dev-main 2025-09-18 11:01 UTC

This package is auto-updated.

Last update: 2025-09-18 11:05:39 UTC


README

PHP Version License Tests

A comprehensive, framework-agnostic PHP package for data sanitization and validation. Built with PSR-12 and PSR-4 compliance, this package provides seamless integration with Laravel, Symfony, and standalone PHP projects.

๐Ÿš€ Features

  • Framework Agnostic: Pure PHP core with zero external dependencies
  • PSR Compliant: Follows PSR-12 (Coding Style) and PSR-4 (Autoloader) standards
  • Extensible: Easy to add custom sanitization and validation rules
  • Framework Integrations: Auto-discoverable Service Providers for Laravel and Bundle for Symfony
  • Comprehensive Rules: Built-in sanitization and validation rules
  • Type Safe: Full PHP 8.2+ type declarations
  • Well Tested: Comprehensive test coverage with Pest

๐Ÿ“ฆ Installation

composer require sercankara/sanitizer

๐Ÿ”ง Usage

Standalone PHP

<?php

use GlobalData\Sanitizer\Sanitizer;

$sanitizer = new Sanitizer();

// Basic usage
$result = $sanitizer->process('  hello@example.com  ', ['trim', 'isEmail']);

if ($result->isValid()) {
    echo $result->getSanitizedValue(); // "hello@example.com"
} else {
    foreach ($result->getErrors() as $error) {
        echo $error;
    }
}

Laravel Integration

The package automatically registers itself in Laravel applications.

Using the Facade

<?php

use GlobalData\Sanitizer\Framework\Laravel\Facades\Sanitizer;

// In your controller or service
$result = Sanitizer::process('  <script>alert("xss")</script>Hello  ', [
    'trim',
    'stripTags',
    'toLower'
]);

if ($result->isValid()) {
    echo $result->getSanitizedValue(); // "hello"
}

Using Dependency Injection

<?php

namespace App\Http\Controllers;

use GlobalData\Sanitizer\Sanitizer;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function store(Request $request, Sanitizer $sanitizer)
    {
        $result = $sanitizer->process($request->input('email'), ['trim', 'isEmail']);
        
        if (!$result->isValid()) {
            return back()->withErrors($result->getErrors());
        }
        
        // Process the sanitized email
        $email = $result->getSanitizedValue();
    }
}

Publishing Configuration

php artisan vendor:publish --tag=sanitizer-config

Symfony Integration

Register the Bundle

Add to config/bundles.php:

<?php

return [
    // ... other bundles
    GlobalData\Sanitizer\Framework\Symfony\SanitizerBundle::class => ['all' => true],
];

Using the Service

<?php

namespace App\Controller;

use GlobalData\Sanitizer\Sanitizer;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class UserController extends AbstractController
{
    public function __construct(
        private Sanitizer $sanitizer
    ) {}

    public function store(Request $request)
    {
        $result = $this->sanitizer->process($request->get('email'), ['trim', 'isEmail']);
        
        if (!$result->isValid()) {
            // Handle validation errors
            return $this->json(['errors' => $result->getErrors()], 400);
        }
        
        // Process the sanitized email
        $email = $result->getSanitizedValue();
    }
}

Configuration

Create config/packages/sanitizer.yaml:

sanitizer:
    filterXSS:
        allowed_tags: ['p', 'br', 'strong', 'em']
        allowed_attributes: ['class', 'id']
    custom_rules:
        customRule: \App\Rules\CustomRule::class

๐Ÿ“‹ Available Rules

Sanitization Rules

Rule Description Example
trim Remove whitespace from beginning and end ' hello ' โ†’ 'hello'
stripTags Remove HTML and PHP tags '<p>Hello</p>' โ†’ 'Hello'
escapeHtml Escape HTML entities '<script>' โ†’ '&lt;script&gt;'
filterXSS Filter XSS attacks '<script>alert("xss")</script>' โ†’ 'alert("xss")'
toLower Convert to lowercase 'HELLO' โ†’ 'hello'
toUpper Convert to uppercase 'hello' โ†’ 'HELLO'

Validation Rules

Rule Description Parameters Example
required Value must not be empty None '' โ†’ โŒ
isEmail Must be a valid email None 'user@example.com' โ†’ โœ…
isNumeric Must be numeric None '123' โ†’ โœ…
isInteger Must be an integer None '123' โ†’ โœ…
maxLength Maximum string length Length 'hello' with maxLength:10 โ†’ โœ…
minLength Minimum string length Length 'hello' with minLength:3 โ†’ โœ…

๐Ÿ”ง Configuration

Laravel Configuration

After publishing the config file, you can customize the sanitizer:

<?php
// config/sanitizer.php

return [
    'filterXSS' => [
        'allowed_tags' => ['p', 'br', 'strong', 'em'],
        'allowed_attributes' => ['class', 'id', 'title'],
    ],
    'custom_rules' => [
        'customRule' => \App\Rules\CustomRule::class,
    ],
];

Symfony Configuration

# config/packages/sanitizer.yaml
sanitizer:
    filterXSS:
        allowed_tags: ['p', 'br', 'strong', 'em']
        allowed_attributes: ['class', 'id', 'title']
    custom_rules:
        customRule: \App\Rules\CustomRule::class

๐Ÿ› ๏ธ Creating Custom Rules

Create a custom rule by implementing the RuleInterface:

<?php

namespace App\Rules;

use GlobalData\Sanitizer\Contracts\RuleInterface;
use GlobalData\Sanitizer\Exceptions\InvalidRuleException;

class CustomRule implements RuleInterface
{
    public function apply(mixed $value, array $parameters = []): mixed
    {
        // Your custom logic here
        if (/* your validation logic */) {
            throw InvalidRuleException::forRule($this->getName(), $value, $parameters);
        }
        
        return $value; // or sanitized value
    }

    public function getName(): string
    {
        return 'customRule';
    }
}

Register your custom rule in the configuration:

// config/sanitizer.php
return [
    'custom_rules' => [
        'customRule' => \App\Rules\CustomRule::class,
    ],
];

๐Ÿงช Testing

# Run tests
composer test

# Run tests with coverage
composer test-coverage

๐Ÿš€ Running Examples

# Run standalone PHP example
composer example:standalone

# Run advanced usage example
composer example:advanced

# Run all examples
composer example:all

๐Ÿ“š Examples

Complete Form Validation

<?php

use GlobalData\Sanitizer\Sanitizer;

$sanitizer = new Sanitizer();

// User registration data
$data = [
    'name' => '  John Doe  ',
    'email' => '  john@example.com  ',
    'password' => 'mypassword123',
    'age' => '25'
];

$rules = [
    'name' => ['trim', 'required', 'minLength:2', 'maxLength:50'],
    'email' => ['trim', 'required', 'isEmail'],
    'password' => ['required', 'minLength:8'],
    'age' => ['required', 'isInteger']
];

$results = [];
foreach ($data as $field => $value) {
    $results[$field] = $sanitizer->process($value, $rules[$field]);
}

// Check if all fields are valid
$allValid = collect($results)->every(fn($result) => $result->isValid());

if ($allValid) {
    // Process sanitized data
    $sanitizedData = collect($results)->map(fn($result) => $result->getSanitizedValue());
} else {
    // Handle validation errors
    $errors = collect($results)
        ->filter(fn($result) => !$result->isValid())
        ->flatMap(fn($result) => $result->getErrors());
}

XSS Protection

<?php

use GlobalData\Sanitizer\Sanitizer;

$sanitizer = new Sanitizer();

$userInput = '<script>alert("XSS")</script><p>Hello World</p>';

$result = $sanitizer->process($userInput, [
    'filterXSS',
    'stripTags',
    'trim'
]);

echo $result->getSanitizedValue(); // "Hello World"

๐Ÿš€ Example Files

We provide comprehensive example files to help you get started quickly:

Standalone PHP Example

php examples/standalone.php

This example demonstrates:

  • Basic email validation and sanitization
  • XSS protection
  • Form validation
  • Custom configuration
  • Error handling

Laravel Integration Example

# See examples/laravel-example.php

This example shows:

  • Controller integration with dependency injection
  • Using the Facade
  • Custom rule creation
  • Form validation in Laravel
  • Error handling and JSON responses

Symfony Integration Example

# See examples/symfony-example.php

This example demonstrates:

  • Service injection in Symfony controllers
  • Custom rule implementation
  • Configuration setup
  • API endpoint validation

Advanced Usage Example

php examples/advanced-usage.php

This example covers:

  • Batch processing
  • Custom rule implementation
  • Complex HTML sanitization
  • Data validation pipelines
  • Performance testing

๐Ÿ› ๏ธ Quick Start Examples

Basic Usage

<?php
require_once 'vendor/autoload.php';

use GlobalData\Sanitizer\Sanitizer;

$sanitizer = new Sanitizer();

// Simple email validation
$result = $sanitizer->process('  user@example.com  ', ['trim', 'isEmail']);
if ($result->isValid()) {
    echo "Valid email: " . $result->getSanitizedValue();
} else {
    echo "Invalid email: " . implode(', ', $result->getErrors());
}

Laravel Quick Start

<?php
// In your Laravel controller
use GlobalData\Sanitizer\Sanitizer;

class UserController extends Controller
{
    public function store(Request $request, Sanitizer $sanitizer)
    {
        $result = $sanitizer->process($request->input('email'), ['trim', 'isEmail']);
        
        if (!$result->isValid()) {
            return back()->withErrors($result->getErrors());
        }
        
        // Use sanitized email
        $email = $result->getSanitizedValue();
    }
}

Symfony Quick Start

<?php
// In your Symfony controller
use GlobalData\Sanitizer\Sanitizer;

class UserController extends AbstractController
{
    public function __construct(private Sanitizer $sanitizer) {}
    
    public function create(Request $request): JsonResponse
    {
        $result = $this->sanitizer->process($request->get('email'), ['trim', 'isEmail']);
        
        if (!$result->isValid()) {
            return $this->json(['errors' => $result->getErrors()], 400);
        }
        
        // Use sanitized email
        $email = $result->getSanitizedValue();
    }
}

๐Ÿค Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ†˜ Support

If you have any questions or need help, please open an issue on GitHub.

Made with โค๏ธ by Sercan Kara