Looking to hire Laravel developers? Try LaraJobs

laravel-fuzzy-validation maintained by cavalheri

Description
Fuzzy validation rules for Laravel with approximate string matching support.
Last update
2026/05/25 21:30 (dev-master)
License
Links
Downloads
1

Comments
comments powered by Disqus

Laravel Fuzzy Validation

Tests Latest Version on Packagist License

Fuzzy validation rules for Laravel with approximate string matching support. Prevent near-duplicate entries such as The Matrix vs Th3 M4tr1x or Café vs Cafe.

Requirements

  • PHP 8.3+
  • Laravel 13+

Installation

composer require cavalheri/laravel-fuzzy-validation

The package supports auto-discovery. Publish the configuration file when needed:

php artisan vendor:publish --tag=fuzzy-validation-config

Quick Start

Fluent Rule API

use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;

$validator = Validator::make($request->all(), [
    'title' => [
        'required',
        Rule::fuzzyUnique('movies', 'title')
            ->threshold(85)
            ->ignore($movie?->id)
            ->normalize(),
    ],
]);

String Syntax

'title' => 'required|fuzzy_unique:movies,title'

You can pass additional parameters:

'title' => 'required|fuzzy_unique:movies,title,90,normalize,driver=jaro_winkler,ignore=1'

Configuration

// config/fuzzy-validation.php

return [
    'driver' => env('FUZZY_VALIDATION_DRIVER', 'similar_text'),
    'threshold' => (int) env('FUZZY_VALIDATION_THRESHOLD', 85),

    'normalization' => [
        'lowercase' => true,
        'trim' => true,
        'collapse_spaces' => true,
        'remove_accents' => true,
        'leetspeak' => false,
    ],

    'messages' => [
        'fuzzy_unique' => 'The :attribute is too similar to an existing value.',
    ],
];

Features

Similarity Drivers

Driver Description
similar_text PHP native similar_text() (default)
levenshtein Levenshtein distance converted to percentage
jaro_winkler Jaro-Winkler algorithm implementation

Select a driver globally or per rule:

Rule::fuzzyUnique('movies', 'title')->driver('jaro_winkler')

Normalization Pipeline

Enable normalization on a rule:

Rule::fuzzyUnique('movies', 'title')->normalize()

Available normalizers:

  • lowercase
  • trim
  • collapse spaces
  • remove accents
  • optional leetspeak (4a, 3e, 1i, 0o, 5s, 7t)

Enable leetspeak normalization:

Rule::fuzzyUnique('movies', 'title')->normalize()->leetspeak()

Override defaults per rule:

Rule::fuzzyUnique('movies', 'title')->normalize([
    'remove_accents' => false,
    'leetspeak' => true,
])

Threshold

Similarity is measured from 0 to 100. Higher values require closer matches.

Rule::fuzzyUnique('movies', 'title')->threshold(90)

Ignore Records

Works like Laravel's built-in unique rule:

Rule::fuzzyUnique('movies', 'title')->ignore($movie->id)
Rule::fuzzyUnique('movies', 'title')->ignore($movie)
Rule::fuzzyUnique('movies', 'title')->ignore($uuid, 'uuid')

Additional Constraints

Rule::fuzzyUnique('movies', 'title')->where('published', true)

Rule::fuzzyUnique('movies', 'title')->where(function ($query) {
    $query->where('tenant_id', tenant('id'));
})

Custom Similarity Drivers

Implement the SimilarityDriver contract:

use Cavalheri\LaravelFuzzyValidation\Contracts\SimilarityDriver;

final class MyDriver implements SimilarityDriver
{
    public function compare(string $first, string $second): float
    {
        // Return similarity percentage (0-100)
    }
}

Register the driver:

use Cavalheri\LaravelFuzzyValidation\Similarity\SimilarityManager;

app(SimilarityManager::class)->extend('my_driver', MyDriver::class);

Use it in validation:

Rule::fuzzyUnique('movies', 'title')->driver('my_driver')

Database Support

The package works with any database supported by Laravel's query builder:

  • MySQL
  • PostgreSQL
  • SQLite

Validation Message

Default message:

The :attribute is too similar to an existing value.

Customize via config or language files:

'fuzzy-validation.messages.fuzzy_unique' => 'This title is too close to an existing movie.',

Testing

composer test

Changelog

See CHANGELOG.md.

License

The MIT License (MIT). See LICENSE for details.