PHPackages                             deligoez/laravel-model-hashid - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. deligoez/laravel-model-hashid

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

deligoez/laravel-model-hashid
=============================

Generate, Save, and Route Stripe/Youtube-like Hash IDs for Laravel Eloquent Models

v4.1.0(4mo ago)166120.3k↓39.7%21MITPHPPHP ^8.3CI passing

Since Sep 4Pushed 4mo ago2 watchersCompare

[ Source](https://github.com/deligoez/laravel-model-hashid)[ Packagist](https://packagist.org/packages/deligoez/laravel-model-hashid)[ Docs](https://github.com/deligoez/laravel-model-hashid)[ RSS](/packages/deligoez-laravel-model-hashid/feed)WikiDiscussions main Synced 2w ago

READMEChangelog (10)Dependencies (34)Versions (21)Used By (0)

[![](https://camo.githubusercontent.com/3331aba0d1e8b2c54077a3791c9394ddcfe43a0bf516364756b906c6d7d0c553/68747470733a2f2f62616e6e6572732e6265796f6e64636f2e64652f4c61726176656c2532304d6f64656c2532304861736849642e706e673f7468656d653d6c69676874267061636b6167654d616e616765723d636f6d706f7365722b72657175697265267061636b6167654e616d653d64656c69676f657a2532466c61726176656c2d6d6f64656c2d686173686964267061747465726e3d627562626c6573267374796c653d7374796c655f32266465736372697074696f6e3d47656e65726174652532432b536176652532432b616e642b526f7574652b5374726970652d6c696b652b486173684964732b666f722b4c61726176656c2b456c6f7175656e742b4d6f64656c73266d643d312673686f7757617465726d61726b3d3026666f6e7453697a653d313530707826696d616765733d68617368746167267769647468733d34303026686569676874733d343030)](https://github.com/deligoez/laravel-model-hashid)

[![Latest Version on Packagist](https://camo.githubusercontent.com/6dbe447e7808c47e515cff2b0752df498a70cb2c0881a3a60a9a4fe94276f46a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f64656c69676f657a2f6c61726176656c2d6d6f64656c2d6861736869642e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/deligoez/laravel-model-hashid)[![Total Downloads](https://camo.githubusercontent.com/614e2377cb3b105a797305911df2801ea37660ad4d73dbb18552bd426ccb9f6b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f64656c69676f657a2f6c61726176656c2d6d6f64656c2d6861736869642e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/deligoez/laravel-model-hashid)[![Packagist](https://camo.githubusercontent.com/90d8f7c28e3ed55dcd6fd9ec5efdf9dc7894d29b2232785bcacb3729b360dc06/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f64656c69676f657a2f6c61726176656c2d6d6f64656c2d686173686964)](https://camo.githubusercontent.com/90d8f7c28e3ed55dcd6fd9ec5efdf9dc7894d29b2232785bcacb3729b360dc06/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f64656c69676f657a2f6c61726176656c2d6d6f64656c2d686173686964)[![CI](https://github.com/deligoez/laravel-model-hashid/actions/workflows/ci.yml/badge.svg)](https://github.com/deligoez/laravel-model-hashid/actions/workflows/ci.yml)[![Open Source Love](https://camo.githubusercontent.com/0ed67edbac694b796f178a40cf685e33e1c7d885826cdfd192a9077be1ff5a9b/68747470733a2f2f6261646765732e66726170736f66742e636f6d2f6f732f76332f6f70656e2d736f757263652e7376673f763d313032)](https://github.com/ellerbrock/open-source-badge/)

Generate, save, and route [Stripe-like](https://gist.github.com/fnky/76f533366f75cf75802c8052b577e2a5) Hash Ids for your Laravel Eloquent Models.

Hash Ids are short, unique, and non-sequential identifiers that hide database row numbers from users. For more information, visit [hashids.org](https://hashids.org/).

For a `User` model with an id of `1234`, you can generate Hash Ids like `user_kqYZeLgo`.

```
https://your-app.com/user/1234          --> before
https://your-app.com/user/user_kqYZeLgo --> after

```

You have complete control over Hash Id length, prefix, separator, and alphabet. Check out the [configuration](#configuration) section for details.

Table of Contents
-----------------

[](#table-of-contents)

- [Requirements](#requirements)
- [Installation](#installation)
- [Usage](#usage)
    - [Hash Id Generation](#hash-id-generation)
    - [Query Builder Functions](#query-builder-functions)
    - [Route Model Binding (Optional)](#route-model-binding-optional)
    - [Saving Hash Ids to Database (Optional)](#saving-hash-ids-to-database-optional)
- [Generic Hash Ids](#generic-hash-ids)
- [Blueprint Macro](#blueprint-macro)
- [Hash Id Cast](#hash-id-cast)
- [Serialization](#serialization)
- [Blade Directive](#blade-directive)
- [Decrypting Hash Ids in Form Requests](#decrypting-hash-ids-in-form-requests)
- [Artisan Commands](#artisan-commands)
- [Validation](#validation)
- [Hash Id Terminology](#hash-id-terminology)
- [Configuration](#configuration)
- [Upgrading](#upgrading)
- [Testing](#testing)
- [Changelog](#changelog)
- [Contributing](#contributing)
- [Security Vulnerabilities](#security-vulnerabilities)
- [Credits](#credits)
- [License](#license)

Requirements
------------

[](#requirements)

PackagePHPLaravel^4.0^8.3^11.0, ^12.0, ^13.0^3.0^8.2^9.0 - ^11.0^2.0^8.1^9.0 - ^12.0^1.0^8.0^8.0Installation
------------

[](#installation)

1. Install via Composer: ```
    composer require deligoez/laravel-model-hashid
    ```
2. Publish the config file: ```
    php artisan vendor:publish --provider="Deligoez\LaravelModelHashId\LaravelModelHashIdServiceProvider" --tag="config"
    ```

Usage
-----

[](#usage)

### Hash Id Generation

[](#hash-id-generation)

Add the `HasHashId` trait to any Eloquent model:

```
use Illuminate\Database\Eloquent\Model;
use Deligoez\LaravelModelHashId\Traits\HasHashId;

class User extends Model
{
    use HasHashId;
}
```

This gives you `hashId` and `hashIdRaw` attributes, plus a `keyFromHashId()` static method:

```
$user = User::find(1234);

$user->hashId;    // 'user_kqYZeLgo'
$user->hashIdRaw; // 'kqYZeLgo'

User::keyFromHashId('user_kqYZeLgo'); // 1234
```

### Query Builder Functions

[](#query-builder-functions)

All finding-related query builder functions work with Hash Ids:

```
// Find a model by its Hash Id
User::findByHashId('user_kqYZeLgo');

// Find multiple models by their Hash Ids
User::findManyByHashId(['user_kqYZeLgo', 'user_ZeLgokqY']);

// Find or throw ModelNotFoundException
User::findOrFailByHashId('user_kqYZeLgo');

// Find or execute a callback
User::findOrByHashId('user_kqYZeLgo');

// Find or return a new model instance
User::findOrNewByHashId('user_kqYZeLgo');

// Where clause using Hash Id
User::whereHashId('user_kqYZeLgo');

// Where not clause using Hash Id
User::whereHashIdNot('user_kqYZeLgo');
```

### Route Model Binding (Optional)

[](#route-model-binding-optional)

Add the `HasHashIdRouting` trait to enable route model binding with Hash Ids:

```
use Illuminate\Database\Eloquent\Model;
use Deligoez\LaravelModelHashId\Traits\HasHashIdRouting;

class User extends Model
{
    use HasHashIdRouting;
}
```

#### Implicit Binding

[](#implicit-binding)

```
// GET /users/user_kqYZeLgo
Route::get('/users/{user}', function (User $user) {
    return $user;
});
```

#### Explicit Binding

[](#explicit-binding)

Register a custom model key in your `RouteServiceProvider`:

```
Route::model('hash_id', User::class);
```

```
// GET /users/user_kqYZeLgo
Route::get('/users/{hash_id}', function (User $user) {
    return $user;
});
```

### Saving Hash Ids to Database (Optional)

[](#saving-hash-ids-to-database-optional)

Add the `SavesHashId` trait to automatically persist Hash Ids:

```
use Illuminate\Database\Eloquent\Model;
use Deligoez\LaravelModelHashId\Traits\SavesHashId;

class User extends Model
{
    use SavesHashId;
}
```

Set the `database_column` in your configuration file (default: `hash_id`). You can configure it globally or per model.

> Hash Id generation works **on the fly** -- saving to the database is not required for generation or decoding.

> Since Hash Id generation requires an integer model key, saving to the database results in an additional query after model creation.

Generic Hash Ids
----------------

[](#generic-hash-ids)

Use the `HashId` utility class to encode and decode integers without a model:

```
use Deligoez\LaravelModelHashId\Support\HashId;

// Encode with default config
HashId::encode(1234);                                    // 'kqYZeLgo...'

// Encode with prefix and separator
HashId::encode(1234, prefix: 'tok', separator: '_');     // 'tok_kqYZeLgo...'

// Encode with custom salt, length, and alphabet
HashId::encode(1234, salt: 'custom', length: 8);

// Decode
HashId::decode('tok_kqYZeLgo...', prefix: 'tok');        // 1234

// Build a standalone generator
$generator = HashId::buildGenerator(salt: 'my-salt', length: 10);
```

All parameters are optional and fall back to config values.

Blueprint Macro
---------------

[](#blueprint-macro)

A `hashId()` macro is available on the `Blueprint` class for migrations:

```
Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->hashId();              // nullable, unique string column (default: 'hash_id')
    $table->hashId('custom_hash'); // custom column name
    $table->timestamps();
});
```

The default column name comes from the `database_column` config value.

Hash Id Cast
------------

[](#hash-id-cast)

Use `HashIdCast` to cast attributes in your model:

```
use Deligoez\LaravelModelHashId\Casts\HashIdCast;

class User extends Model
{
    use HasHashId;

    protected $casts = [
        'hash_id' => HashIdCast::class,
    ];
}
```

- `get()`: returns the stored string as-is
- `set()`: converts integers to a full Hash Id, passes strings through, and handles null

Serialization
-------------

[](#serialization)

Add the `SerializesHashId` trait to replace the primary key with the Hash Id in serialized output (arrays and JSON):

```
use Deligoez\LaravelModelHashId\Traits\SerializesHashId;

class User extends Model
{
    use HasHashId;
    use SerializesHashId;
}

$user = User::find(1234);
$user->toArray();  // ['id' => 'user_kqYZeLgo', 'name' => 'John', ...]
$user->toJson();   // {"id":"user_kqYZeLgo","name":"John",...}
```

This follows the Stripe pattern of exposing Hash Ids in API responses. It respects `$hidden` and `$visible` attributes.

Blade Directive
---------------

[](#blade-directive)

Use the `@hashid` directive to output a model's Hash Id in Blade templates:

```
{{ $user->name }}
```

The output is XSS-safe via Laravel's `e()` helper.

Decrypting Hash Ids in Form Requests
------------------------------------

[](#decrypting-hash-ids-in-form-requests)

Add the `DecryptsHashIds` trait to a `FormRequest` to automatically convert Hash Id inputs to integer keys after validation:

```
use Deligoez\LaravelModelHashId\Traits\DecryptsHashIds;

class UpdatePostRequest extends FormRequest
{
    use DecryptsHashIds;

    protected array $hashIds = [
        'user_id' => User::class,
        'post_id' => Post::class,
    ];

    public function rules(): array
    {
        return [
            'user_id' => ['required', new ValidHashId(User::class)],
            'post_id' => ['required', new ValidHashId(Post::class)],
        ];
    }
}

// In your controller, $request->user_id is now an integer
```

Artisan Commands
----------------

[](#artisan-commands)

Two Artisan commands are available for encoding and decoding Hash Ids:

```
# Encode a key to a Hash Id
php artisan hashid:encode "App\Models\User" 1234

# Decode a Hash Id (with explicit model)
php artisan hashid:decode "user_kqYZeLgo" "App\Models\User"

# Decode a Hash Id (auto-detect model from registered generators)
php artisan hashid:decode "user_kqYZeLgo"
```

Validation
----------

[](#validation)

Two validation rules are provided for validating Hash Ids in form requests and validators.

### `ValidHashId` — Format Validation (No Database Hit)

[](#validhashid--format-validation-no-database-hit)

Checks if a value is a valid Hash Id format. Optionally validates against a specific model (prefix + decode check).

```
use Deligoez\LaravelModelHashId\Rules\ValidHashId;

// Generic: any decodable Hash Id
'token' => [new ValidHashId]

// Model-specific: must decode for User model
'user_id' => [new ValidHashId(User::class)]
```

### `HashIdExists` — Database Existence Check

[](#hashidexists--database-existence-check)

Checks if a Hash Id corresponds to an existing database record. Equivalent to Laravel's `exists` rule for Hash Ids.

```
use Deligoez\LaravelModelHashId\Rules\HashIdExists;

'user_id' => [new HashIdExists(User::class)]
```

Both rules throw an `InvalidArgumentException` if the given model does not use the `HasHashId` trait.

Hash Id Terminology
-------------------

[](#hash-id-terminology)

A Hash Id consists of three parts:

PartExampleRequiredPrefix`user`NoSeparator`_`NoRaw Hash Id`kqYZeLgo`YesYou can generate Hash Ids with or without a prefix. Set `prefix_length` to `0` in the config to disable prefixes.

Configuration
-------------

[](#configuration)

Publish the config file and customize:

```
php artisan vendor:publish --provider="Deligoez\LaravelModelHashId\LaravelModelHashIdServiceProvider" --tag="config"
```

OptionDefaultDescription`salt``'your-secret-salt-string'`Salt for Hash Id generation. **Change this before deploying.**`length``13`Raw Hash Id length (excluding prefix and separator)`alphabet``'abcdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ234567890'`Characters used in Hash Id generation (min 16 unique chars)`prefix_length``3`Prefix length from class name. `-1` for full name, `0` for none`prefix_case``'lower'`Prefix case: `lower`, `upper`, `camel`, `snake`, `kebab`, `title`, `studly`, `plural_studly``separator``'_'`Separator between prefix and raw Hash Id`database_column``'hash_id'`Database column name for `SavesHashId` trait### Model-Specific Configuration

[](#model-specific-configuration)

Override any option per model in the `model_generators` array:

```
'model_generators' => [
    App\Models\User::class => [
        'salt'            => 'user-specific-salt',
        'length'          => 8,
        'prefix_length'   => -1, // full class name as prefix
        'separator'       => '-',
    ],

    App\Models\Post::class => [
        'prefix' => 'article', // custom prefix (not generated from class name)
    ],
],
```

Upgrading
---------

[](#upgrading)

If you are upgrading from v3 to v4, please see the [UPGRADE guide](UPGRADE.md) for a list of breaking changes.

Testing
-------

[](#testing)

```
composer test
```

This runs the full quality gate: Rector, Pint, PHPStan, and Pest.

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Yunus Emre Deligoz](https://github.com/deligoez)
- [Scott Plunkett](https://github.com/plunkettscott)
- [Wade](https://github.com/striebwj)
- [Laravel Shift](https://github.com/laravel-shift)
- [Faruk](https://github.com/frkcn)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

60

—

FairBetter than 98% of packages

Maintenance77

Regular maintenance activity

Popularity50

Moderate usage in the ecosystem

Community20

Small or concentrated contributor base

Maturity76

Established project with proven stability

 Bus Factor1

Top contributor holds 74.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~120 days

Recently: every ~103 days

Total

15

Last Release

125d ago

Major Versions

1.0.2 → 2.0.02022-02-21

2.4.1 → v3.0.02024-07-23

3.1.1 → v4.0.02026-03-02

PHP version history (6 changes)1.0.0PHP ^8.0

2.0.0PHP ^8.0 || ^8.1

2.3.0PHP ^8.0|^8.1|^8.2

v3.0.0PHP ^8.2|^8.3

3.1.0PHP ^8.2|^8.3|^8.4

v4.0.0PHP ^8.3

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/3030815?v=4)[Yunus Emre Deligöz](/maintainers/deligoez)[@deligoez](https://github.com/deligoez)

---

Top Contributors

[![deligoez](https://avatars.githubusercontent.com/u/3030815?v=4)](https://github.com/deligoez "deligoez (361 commits)")[![mkeremcansev](https://avatars.githubusercontent.com/u/76810832?v=4)](https://github.com/mkeremcansev "mkeremcansev (61 commits)")[![YunusEmreNalbant](https://avatars.githubusercontent.com/u/29780061?v=4)](https://github.com/YunusEmreNalbant "YunusEmreNalbant (22 commits)")[![frkcn](https://avatars.githubusercontent.com/u/374634?v=4)](https://github.com/frkcn "frkcn (22 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (6 commits)")[![plunkettscott](https://avatars.githubusercontent.com/u/4952170?v=4)](https://github.com/plunkettscott "plunkettscott (6 commits)")[![bensherred](https://avatars.githubusercontent.com/u/22666637?v=4)](https://github.com/bensherred "bensherred (2 commits)")[![striebwj](https://avatars.githubusercontent.com/u/14165147?v=4)](https://github.com/striebwj "striebwj (1 commits)")[![terranc](https://avatars.githubusercontent.com/u/224353?v=4)](https://github.com/terranc "terranc (1 commits)")

---

Tags

hashidslaravellaravel-packagephplaravellaravel-packagehashidsdeligoezlaravel-model-hashid

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/deligoez-laravel-model-hashid/health.svg)

```
[![Health](https://phpackages.com/badges/deligoez-laravel-model-hashid/health.svg)](https://phpackages.com/packages/deligoez-laravel-model-hashid)
```

###  Alternatives

[vinkla/hashids

A Hashids bridge for Laravel

2.1k14.6M78](/packages/vinkla-hashids)[codewithdennis/filament-select-tree

The multi-level select field enables you to make single selections from a predefined list of options that are organized into multiple levels or depths.

329575.9k35](/packages/codewithdennis-filament-select-tree)[tomshaw/electricgrid

A feature-rich Livewire package designed for projects that require dynamic, interactive data tables.

119.8k](/packages/tomshaw-electricgrid)[tarfin-labs/event-machine

Event-driven state machines for Laravel with event sourcing, type-safe context, and full audit trail.

219.6k](/packages/tarfin-labs-event-machine)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
