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.
Table of contents
- Features
- Compatibility Table
- Installation
- Usage
- Hash Id Terminology
- Configuration
- Roadmap
- Testing
- Used By
- Changelog
- Contributing
- Security Vulnerabilities
- Credits
- License
Features
- Customizable Hash Id Generation
- Hash Id Salt
- Length
- HashID Alphabet
- Model Prefix Length and Case
- Separator
- Model Specific Hash Id Generation
- Define separate configurations per Model
- Route (Model) Binding using Hash Ids (optional)
- Automatically save Hash Ids to the database (optional)
Compatibility Table
The table below shows the compatibility across Laravel, PHP, and this package's current version.
Package Version | Laravel version | PHP version | Compatible |
---|---|---|---|
^1.0 | 8.* | 8.0.* |
|
8.* | 7.4.* |
|
|
8.* | 7.3.* |
|
|
7.x | * |
|
Installation
- Install via Composer:
composer require deligoez/laravel-model-hashid
- Publish the config file:
php artisan vendor:publish --provider="Deligoez\LaravelModelHashId\LaravelModelHashIdServiceProvider" --tag="config"
Usage
Model Hash Id Generation
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;
...
}
Model Attributes and Static Model Functions
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
Query Builder Functions
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 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');
Routing and Route Model Binding (Optional)
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;
...
}
Route Model Binding (Implicit)
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;
});
Route Model Binding (Explicit)
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;
});
Saving Hash Ids to the Database (Optional)
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.
Hash Id Terminology
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.
Configuration
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',
// ],
],
];
Roadmap
- Custom Model Prefixes (Not generated from a Model name)
- Hash Id Validation Rules
- Generic Generators (Not bound to a Laravel Model)
Testing
composer test
Used By
This project is used by the following companies/products, you can add yours too:
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.