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 Normalizer Laravel Package

nwidart/laravel-normalizer

A Laravel package for normalizing data into consistent, predictable formats. Define custom normalizers to clean and transform input, making validation and storage simpler across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

Before your first composer require, read the source. The package is pre-1.0, last tagged in July 2016 (0.2, PHP 7 scalar type hints), and has no published API reference. composer require nwidart/laravel-normalizer will resolve on modern PHP only if the composer.json constraints permit it — check the php and illuminate/* requirements first and, if needed, pin explicitly:

composer require nwidart/laravel-normalizer:^0.2

Where to look first, in order:

  1. src/ — the whole package is small. Read every class top to bottom in one sitting; you need to know the exact contract (normalize() signature, return type, whether it accepts scalars/arrays/Arrayable).
  2. composer.json — confirm the PHP floor and which Illuminate version was targeted. This was written against Laravel 5.x-era Illuminate.
  3. README.md — the usage example, if present, is your fastest path to a working call.
  4. tests/ (if shipped) — the most reliable description of intended behavior for a dormant package.

Auto-discovery: if the package ships a service provider, Laravel 5.5+ will register it via extra.laravel.providers. If it predates that convention (likely for a 2016 package), add it manually to config/app.php providers and check whether a facade alias is needed.

First use case — normalize a form request before validation or persistence. The natural entry point is the boundary where untrusted, shape-variable input arrives:

$normalized = app(SomeNormalizer::class)->normalize($request->all());

Start with one normalizer class that handles a single, well-understood payload (e.g., a phone/email/date-bearing "contact" form), assert the output shape in a unit test, and only then wire it into a controller. Do not introduce it across your codebase until that one path is proven — the payoff (centralized normalization) is real, but the package gives you no safety net.

Implementation Patterns

1. Wrap normalization in your own interface, not the package's. Because the package is unmaintained and pre-1.0, do not let nwidart\laravel-normalizer types leak into your domain code. Define a small Normalizer contract of your own and let one adapter implementation delegate to the package:

interface Normalizer { public function normalize(array $input): array; }

class PackageNormalizer implements Normalizer
{
    public function normalize(array $input): array
    {
        return app(\Nwidart\Normalizer\...::class)->normalize($input);
    }
}

This is the single most important pattern in this assessment: it means swapping the package for 40 lines of hand-rolled code (or laravel-data/spatie/laravel-data later) is a one-file change, not a refactor.

2. Normalize at the ingress boundary, then validate. Order matters: normalize → validate → persist. Normalizing first means your FormRequest rules see a predictable shape (consistent casing, trimmed strings, arrays where scalars were allowed), so rules stay simple and don't need prepareForValidation() branches.

protected function prepareForValidation(): void
{
    $this->merge(app(ContactNormalizer::class)->normalize($this->all()));
}

3. Model attribute normalization via mutators. For attribute-level rules, call the normalizer from an Eloquent mutator or a small HasNormalizedAttributes trait so that any write path (seeders, jobs, imports) gets the same treatment as HTTP input:

public function setPhoneAttribute($value): void
{
    $this->attributes['phone'] = $this->normalizer->normalize(['phone' => $value])['phone'];
}

4. Centralize per-payload normalizers, one per DTO/screen. Create App\Normalizers\* classes keyed to a specific payload rather than one god-normalizer. Composition is fine — a UserNormalizer can call an AddressNormalizer — but keep each class's input shape narrow and documented in a docblock, since the package itself documents nothing.

5. Integrate at job/import boundaries too. The highest-value use is not HTTP at all: CSV imports, webhooks, and queue payloads are where shape drift actually bites. Normalize once when the job is dispatched or when the import row is read, and log the pre/post shape on failure.

6. Bind normalizers in a service provider so they are injectable and testable, and so you have one obvious place to change when you eventually replace the package.

Gotchas and Tips

  • Assume no upstream fixes. Last release 2016-07-27, 12 stars. Treat bugs as yours to patch — fork it, vendor it, or wrap it (see the adapter pattern above). Add composer.lock and pin ~0.2.0; a 0.x minor bump is allowed to break you under semver.
  • PHP 8 compatibility is unverified. The 0.2 release added PHP 7 scalar type hints. Loose coercions that worked in PHP 5 ("1" → 1, null → int) now throw TypeError on PHP 7+ and are stricter still on PHP 8. Test with declare(strict_types=1) in your files too, since that changes call-site behavior.
  • Nullable inputs are the classic failure. Normalizers are usually fed $request->input('x'), which is null when absent. If the package's signature declares string/array without a ?, you will get runtime TypeErrors that no amount of validation-rule tweaking fixes. Guard with ?? [] / ?? '' at the call site.
  • Don't subclass package classes. If the 0.2 type hints landed on non-final methods, extending them risks signature-compatibility errors across PHP versions. Compose instead of extending.
  • Auto-discovery may not fire. A 2016-era package likely lacks the extra.laravel block. If the container can't resolve the normalizer, register it manually — that's usually the whole problem.
  • Debugging: assert the shape, not the equality of whole arrays. Snapshot the key set and the type of each value in a test (assertSame(['phone' => 'string', ...], array_map('gettype', $out))). When behavior looks wrong, diff input-vs-output on one fixture rather than reading the package source again — the package is small enough to single-step in a debugger in one pass.
  • Config quirks: expect none. There is no evidence of a publishable config file. Do not assume php artisan vendor:publish gives you anything; if config/normalizer.php is referenced in source but absent from your app, defaults live in the package's PHP files and are not overridable without a fork.
  • Extension points are "your own code." Realistically the only extension point is the adapter you wrote in step 1. Lean on Laravel-native tools for the rest: TrimStrings/ConvertEmptyStringsToNull middleware, prepareForValidation(), casts, and Arr::wrap/Arr::only for structural work.
  • Performance is a non-issue; correctness is the issue. No throughput concern at this size. Spend the effort on a round-trip test per normalizer (normalize → validate → persist → read back) instead of micro-benchmarking.
  • Have an exit plan on day one. Write down the trigger for replacing it (e.g., "second PHP 8 blocker" or "package breaks on next Laravel major"). With the adapter in place the replacement is a ~40-line class; without it, it's a codebase-wide refactor. Given the 0.12 score and nine-year dormancy, plan for that day to arrive.
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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log