Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Request Sanitizer Laravel Package

arondeparon/laravel-request-sanitizer

Sanitize incoming request data before validation in Laravel. Define reusable sanitizers to trim, cast, or transform input—individually or in pipelines—keeping controllers and form requests clean. Integrates smoothly with Laravel's validation lifecycle.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and confirm the service provider is auto-discovered (Laravel 5.5+):

composer require arondeparon/laravel-request-sanitizer

If the package ships a config file, publish it so you can register global sanitizers:

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

The first thing to look at is the package's base request class (typically Arondeparon\LaravelRequestSanitizer\Http\Requests\SanitizedFormRequest) and the Sanitizer contract it expects. That contract is the whole package: everything else is a mapping of field names to an ordered list of sanitizer classes that run before validation.

The fastest first use case is an email field that users paste with stray whitespace or capital letters, which then fails a unique rule:

namespace App\Http\Requests;

use Arondeparon\LaravelRequestSanitizer\Http\Requests\SanitizedFormRequest;

class StoreContactRequest extends SanitizedFormRequest
{
    protected $sanitizers = [
        'name'  => [Trim::class, TitleCase::class],
        'email' => [Trim::class, Lowercase::class],
    ];

    public function rules(): array
    {
        return [
            'name'  => ['required', 'string', 'max:255'],
            'email' => ['required', 'email', 'unique:users,email'],
        ];
    }
}

Swap FormRequest for SanitizedFormRequest in the type-hint of your controller method and you are done — the sanitization happens inside the request lifecycle, so $request->validated() contains the cleaned values and your rules run against them.

Implementation Patterns

Ordered pipeline per field. Each field maps to an array; sanitizers execute left-to-right. Put structural cleanups first (Trim, strip tags, normalize whitespace) and formatting last (TitleCase, phone formatting). The output of one feeds the next, so a sanitizer that returns null will short-circuit the rest of the chain.

Custom sanitizers. Write a small class implementing the package's sanitizer contract for domain-specific rules — normalizing Dutch postal codes, stripping currency symbols, converting comma decimals to dots:

class NormalizePostalCode implements Sanitizer
{
    public function sanitize($value)
    {
        return strtoupper(preg_replace('/\s+/', '', (string) $value));
    }
}

Keep these stateless and side-effect-free so they are trivial to unit test.

Shared sanitizer sets. If many requests clean the same fields (e.g. every form with a name and email), either declare a base request class with the common $sanitizers and extend it, or register them as global sanitizers in the config so they apply to every sanitized request. Global sanitizers are convenient but make behavior implicit — prefer explicit per-request declarations for anything domain-specific.

Arrays and nested fields. For array payloads, check whether the package supports wildcard keys (items.*.sku) before assuming it does. If it does not, sanitize the sub-values inside prepareForValidation() and leave the field-level sanitizers to the top-level keys.

Choosing between this and prepareForValidation. Both run before validation. Use the package when you want a declarative, reusable list shared across requests; use prepareForValidation when the transformation needs other request state (route model, auth user, headers). Don't do both for the same field.

Testing. Feature tests against the endpoint are the highest-value check: send a dirty payload, assert the validated data is clean, and assert the DB row has the normalized value. Add unit tests for custom sanitizers with edge inputs (null, empty string, unicode, already-clean values).

Gotchas and Tips

  • Absent fields. Sanitizers may receive null or be skipped for missing keys depending on the package version. Guard custom sanitizers against null and non-strings; returning null unexpectedly can flip required/nullable validation results.
  • Type changes. Sanitizers that return ints, floats, or booleans can conflict with string rules. Either keep sanitizers returning strings and cast later, or make sure your rules expect the type coming out.
  • Order matters more than you think. Trim before Lowercase is harmless; stripping tags before a max length rule is essential. If a length check fails after "cleaning," the chain order is usually the culprit.
  • Never sanitize secrets. Passwords, API tokens, and file uploads should pass through untouched. Trimming a password silently breaks logins for users who intentionally include spaces.
  • unique and exists use the sanitized value. That is usually the point, but be aware that Rule::unique(...)->ignore($id) and case-insensitive collations can still behave differently across databases — test against your actual driver.
  • Silent mutation hides bugs. If a user submits " John " and it's stored as "John", that's fine; if a sanitizer turns "N/A" into "" and the field is required, the error message will confuse. Keep sanitizers narrowly scoped and predictable.
  • Debugging. The quickest probe is dd() inside a sanitizer or a temporary dump($request->all()) at the top of rules(). If the values look right there but not in validated(), the issue is in the rules, not the sanitizers.
  • Config caching. Global sanitizer registration lives in config — run php artisan config:cache after changes in production, and remember cached config will mask edits made directly on the server.
  • Instantiation. Sanitizers are typically resolved per-request. If yours needs dependencies (a lookup table, a locale), check whether the package resolves from the container; if not, keep them dependency-free or inject via a bound singleton.
  • Container of last resort. For one-off or runtime-driven cleaning, the package does not replace middleware. A small middleware that normalizes a header or query string is still the right tool when the data isn't coming from a form request.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource