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.0.1(2mo ago)16498.0k↑15%20MITPHPPHP ^8.3CI passing

Since Sep 4Pushed 2mo 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 1mo ago

READMEChangelog (10)Dependencies (22)Versions (20)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^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

61

—

FairBetter than 99% of packages

Maintenance85

Actively maintained with recent releases

Popularity49

Moderate usage in the ecosystem

Community20

Small or concentrated contributor base

Maturity74

Established project with proven stability

 Bus Factor1

Top contributor holds 74.8% 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 ~126 days

Recently: every ~147 days

Total

14

Last Release

76d 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 (359 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.1k13.3M73](/packages/vinkla-hashids)[ashallendesign/short-url

A Laravel package for creating shortened URLs for your web apps.

1.4k1.9M4](/packages/ashallendesign-short-url)[cybercog/laravel-optimus

An Optimus bridge for Laravel. Id obfuscation based on Knuth's multiplicative hashing method.

192564.1k](/packages/cybercog-laravel-optimus)[larament/seokit

A complete SEO package for Laravel, covering everything from meta tags to social sharing and structured data.

411.9k](/packages/larament-seokit)[lingxi/hashids

A Hashids bridge for Laravel

183.3k](/packages/lingxi-hashids)

PHPackages © 2026

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