Using this package you can generate, save and, route Stripe-like Hash Ids for your Eloquent Models.
Hash Ids are short, unique, and non-sequential, and can generate unique Ids for URLs and hide database row numbers from the user. For more information about Hash Ids please visit hashids.org.
With this package, you can customize Hash Id generation and add a model prefix and also separator.
For a User
model with an id of 1234
, you can generate Hash Ids like user_kqYZeLgo
.
So instead of;
https://your-endpoint.com/user/1234
You can have endpoints like;
https://your-endpoint.com/user/user_kqYZeLgo
You have complete control over your Hash Id length and style. Check out the configuration file for more options.
- Features
- Compatibility Table
- Installation
- Usage
- Hash Id Terminology
- Configuration
- Roadmap
- Testing
- Used By
- Changelog
- Contributing
- Security Vulnerabilities
- Credits
- License
- Customizable Hash Id Generation
- Hash Id Salt
- Length
- HashID Alphabet
- Model Prefix Length and Case
- Separator
- Model Specific Hash Id Generation
- User-defined prefix per Model (optional)
- Define separate configurations per Model
- Route (Model) Binding using Hash Ids (optional)
- Automatically save Hash Ids to the database (optional)
The table below shows the compatibility across Laravel, PHP, and this package's current version.
Package Version | Laravel version | PHP version | Compatible |
---|---|---|---|
^2.0 | 9.* , 10.* | 8.1.* | ✅ |
^1.0 | 8.* | 8.0.* | ✅ |
8.* | 7.4.* | ❌ | |
8.* | 7.3.* | ❌ | |
7.x | * | ❌ |
- Install via Composer:
composer require deligoez/laravel-model-hashid
- Publish the config file:
php artisan vendor:publish --provider="Deligoez\LaravelModelHashId\LaravelModelHashIdServiceProvider" --tag="config"
Add the HasHashId
trait to any Laravel Model that should use Hash Ids.
use Illuminate\Database\Eloquent\Model;
use Deligoez\LaravelModelHashId\Traits\HasHashId;
class ModelA extends Model
{
use HasHashId;
...
}
You will be able to use hashId
and hashIdRaw
attributes and keyFromHashId()
static model function.
$modelA = ModelA::find(1234);
$modelA->hashId; // model_a_kqYZeLgo
$modelA->hashIdRaw; // kqYZeLgo
ModelA::keyFromHashId('model_a_kqYZeLgo') // 1234
You can use all finding related Laravel query builder functions with Hash Ids.
// Find a model by its Hash Id.
ModelA::findByHashId('model_a_kqYZeLgo');
// Find multiple models by their Hash Ids.
ModelA::findManyByHashId(['model_a_kqYZeLgo', 'model_a_ZeLgokqY']);
// Find a model by its Hash Id or throw an exception.
ModelA::findOrFailByHashId('model_a_kqYZeLgo');
// Find a model by its Hash Id or or call a callback.
ModelA::findOrByHashId('model_a_kqYZeLgo');
// Find a model by its Hash Id or return fresh model instance.
ModelA::findOrNewByHashId('model_a_kqYZeLgo');
// Add a where clause on the Hash Id to the query.
ModelA::whereHashId('model_a_kqYZeLgo');
// Add a where not clause on the Hash Id to the query.
ModelA::whereHashIdNot('model_a_kqYZeLgo');
Simply add the HasHashIdRouting
trait to your model that you want to route using Hash Ids.
use Illuminate\Database\Eloquent\Model;
use Deligoez\LaravelModelHashId\Traits\HasHashIdRouting;
class ModelA extends Model
{
use HasHashIdRouting;
...
}
You can define a route and/or controller method like this by Laravel conventions.
// You can call this route with a Hash Id: your-endpoint.com/model-a/model_a_kqYZeLgo
Route::get('/model-a/{modelA}', function (ModelA $modelA) {
// Your ModelA instance
$modelA;
});
You can also define a custom model key on your RouteServiceProvider
.
Route::model('hash_id', ModelA::class);
// You can call this route with a Hash Id: your-endpoint.com/model-a/model_a_kqYZeLgo
Route::get('/model-a/{hash_id}', function ($modelBinding) {
// Your ModelA instance
$modelBinding;
});
You can add the SavesHashId
Trait to any of your Laravel Model that should save the generated Hash Ids.
After that, you should set database_column
setting in the configuration file. You can define database_column
setting
per model separately or for all of your models.
use Illuminate\Database\Eloquent\Model;
use Deligoez\LaravelModelHashId\Traits\SavesHashId;
class ModelA extends Model
{
use SavesHashId;
...
}
All Hash Id generation or decoding methods work ON-THE-FLY. So you DO NOT need to save Hash Ids to the database for that reason.
Since generating a Hash Id requires an integer model id/key, remember that storing the Hash Ids to a database will result in an additional database query.
A typical Hash Id consist of 3 parts.
- Model Prefix (
model_a
) - Separator (
_
) - Raw Hash Id (
kqYZeLgo
)
Model Prefix and Separator are OPTIONAL. You can generate Hash Ids that only contains Raw Hash Ids.
This is the contents of the published config file:
<?php
return [
/*
|--------------------------------------------------------------------------
| Salt String
|--------------------------------------------------------------------------
|
| This salt string is used for generating HashIDs and should be set
| to a random string, otherwise these generated HashIDs will not be
| safe. Please do this definitely before deploying your application!
|
*/
'salt' => env('HASHID_SALT', 'your-secret-salt-string'),
/*
|--------------------------------------------------------------------------
| Raw HashID Length
|--------------------------------------------------------------------------
|
| This is the length of the raw HashID. The model prefix, separator
| and the raw HashID are combined all together. So the Model HashID
| length is the sum of raw HashID, separator, and model prefix lengths.
|
| Default: 13
|
*/
'length' => 13,
/*
|--------------------------------------------------------------------------
| HashID Alphabet
|--------------------------------------------------------------------------
|
| This alphabet will generate raw HashIDs. Please keep in mind that it
| must contain at least 16 unique characters and can't contain spaces.
|
| Default: 'abcdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ234567890'
|
*/
'alphabet' => 'abcdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ234567890',
/*
|--------------------------------------------------------------------------
| Model Prefix Length
|--------------------------------------------------------------------------
|
| Here you can specify the length of the model prefix. By default, they
| will generate it from the first letters of short class name.
| Set it -1 to use full short class name as prefix.
| Set it 0 to not use any prefix at all.
|
| Default: 3
|
*/
'prefix_length' => 3,
/*
|--------------------------------------------------------------------------
| Model Prefix Case
|--------------------------------------------------------------------------
|
| Here you can set the case of the prefix. Please keep in mind that for
| some prefix cases, underscore (‘_’) characters will be added to the
| prefix if your model name is multi word.
|
| Default: 'lower'
|
| Supported: "lower", "upper", "camel", "snake", "kebab",
| "title", "studly", "plural_studly"
|
*/
'prefix_case' => 'lower',
/*
|--------------------------------------------------------------------------
| HashID Model Prefix Separator
|--------------------------------------------------------------------------
|
| Here you can set the separator for your HashIDs. The separator
| will be added between model prefix and the raw HashID.
|
| Default: '_'
|
*/
'separator' => '_',
/*
|--------------------------------------------------------------------------
| HashID Database Column
|--------------------------------------------------------------------------
|
| By using `SavesHashIDs` trait, you can save model HashIDs to database.
| Here you can set the database column name for HashIDs to save.
|
| Default: 'hash_id'
|
*/
'database_column' => 'hash_id',
/*
|--------------------------------------------------------------------------
| Model Specific Generators
|--------------------------------------------------------------------------
|
| Here you can set specific HashID generators for individual Models.
| Each one of the setting above can be defined per model. You can
| see an example below as a comment.
|
*/
'model_generators' => [
// App\Models\User::class => [
// 'salt' => 'your-model-specific-salt-string',
// 'length' => 13,
// 'alphabet' => 'abcdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ234567890',
// 'prefix_length' => 3,
// 'prefix_case' => 'lower',
// 'separator' => '_',
// 'database_column' => 'hash_id',
// ],
// App\Models\Post::class => [
// 'salt' => 'your-model-specific-salt-string',
// 'length' => 13,
// 'alphabet' => 'abcdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ234567890',
// 'prefix' => 'abc', // Custom prefix that is not auto-generated
// 'separator' => '_',
// ],
],
];
- Custom Model Prefixes (Not generated from a Model name) (Thanks to @plunkettscott)
- Hash Id Validation Rules
- Generic Generators (Not bound to a Laravel Model)
composer test
This project is used by the following companies/products, you can add yours too:
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.