#️⃣ Generate, Save, and Route Stripe-like Hash IDs for Laravel Eloquent Models

Overview

Latest Version on Packagist Total Downloads Packagist
Maintainability Rating Reliability Rating Security Rating
Coverage Lines of Code Bugs
Technical Debt Vulnerabilities Code Smells Duplicated Lines (%)
tests code style types Quality Gate Status
Open Source Love

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

  • 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

  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

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.

You might also like...
Magento 2 module to automatically flush the cache whenever you save something in the System Configuration

Yireo AutoFlushCache Magento 2 module to automatically flush the cache whenever you save something in the System Configuration. Do NOT use this in pro

Save items in a bucket, retrieve them later.

Bucket Save items in a bucket, retrieve them later. use Laragear\Bucket\Facades\Buckets; use App\Models\Message; public function send(Message $messag

JSON schema models and generated code to validate and handle various data in PocketMine-MP

DataModels JSON schema models and generated code to validate and handle various data in PocketMine-MP This library uses php-json-schema-model-generato

A Tinder-like experience for Plex Watchlist: swipe and match with another person and find the movie you're gonna watch tonight.

Plex Finder This app's goal is to help choose a film to watch when neither you nor your SO/friend/roommate/whatever is any good at choosing anything.

Allows generate class files parse from json and map json to php object, including multi-level and complex objects;

nixihz/php-object Allows generate class files parse from json and map json to php object, including multi-level and complex objects; Installation You

This module adds a command to easily generate "modules" in Laravel and install them using composer.

Laravel Module Create This module adds a command to easily generate "modules" in Laravel and install them using composer Installation Simply install t

A nice shortcut for group count queries with Eloquent / Laravel

Hightop PHP A nice shortcut for group count queries with Eloquent / Laravel Visit::top('browser'); // [ // 'Chrome' = 63, // 'Safari' = 50, //

Rubix Server is a library for bringing your trained Rubix ML models into production.
Rubix Server is a library for bringing your trained Rubix ML models into production.

Rubix Server is a library for bringing your trained Rubix ML models into production. Inference servers are stand-alone services that run on your private or public network and wrap your trained estimator in an API that can be queried locally or over the network in real-time using standard protocols. In addition, the library provides async-compatible client implementations for making queries to the server from your PHP applications.

A system for auto-decorating models with presenters
A system for auto-decorating models with presenters

Laravel Auto Presenter 7 This package automatically decorates objects bound to views during the view render process. Features Automatically decorate o

Comments
  • Fix Route Model Binding

    Fix Route Model Binding

    This PR is a proof of concept, and hopefully a starting point to fix a bug in the route model binding when the prefix_length is set to -1.

    The first commit is a failing test that validates the bug.

    opened by striebwj 2
  • Add support for model-specific prefix

    Add support for model-specific prefix

    Re-submitting this PR after some clean-up so that you don't have to sift through superfluous commits.

    This is a pretty simple PR to support custom prefixes on a per-model basis, and when none is set the default logic takes precedence. I needed this functionality and saw it was on your project board, so thought I'd give it a go.

    Please let me know if you'd like anything implemented in a different way!

    opened by plunkettscott 1
  • Add custom prefix for specific models

    Add custom prefix for specific models

    Hello!

    This is a pretty simple PR to support custom prefixes on a per-model basis, and when none is set the default logic takes precedence. I needed this functionality and saw it was on your project board, so thought I'd give it a go.

    Please let me know if you'd like anything implemented in a different way!

    opened by plunkettscott 0
Releases(2.2.0)
  • 2.2.0(May 11, 2022)

    What's Changed

    • Introduce findOrByHashId Query Builder method by @deligoez in https://github.com/deligoez/laravel-model-hashid/pull/12
    • Fix route model binding with a prefix length of -1 by @striebwj in https://github.com/deligoez/laravel-model-hashid/pull/9

    New Contributors

    • @striebwj made their first contribution in https://github.com/deligoez/laravel-model-hashid/pull/9

    Full Changelog: https://github.com/deligoez/laravel-model-hashid/compare/2.1.0...2.2.0

    Source code(tar.gz)
    Source code(zip)
  • 2.1.0(May 3, 2022)

    What's Changed

    • Add support for model-specific prefix by @plunkettscott in https://github.com/deligoez/laravel-model-hashid/pull/6

    New Contributors

    • @plunkettscott made their first contribution in https://github.com/deligoez/laravel-model-hashid/pull/6

    Full Changelog: https://github.com/deligoez/laravel-model-hashid/compare/2.0.0...2.1.0

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Feb 21, 2022)

  • 1.0.2(Sep 5, 2021)

  • 1.0.1(Sep 4, 2021)

  • 1.0.0(Sep 4, 2021)

Owner
Yunus Emre Deligöz
Yunus Emre Deligöz
Create Youtube-Like IDs With PHP.

AlphaID Install composer require sy-records/alphaid Usage

沈唁 4 Mar 31, 2022
[READ-ONLY] CakePHP Utility classes such as Inflector, Text, Hash, Security and Xml. This repo is a split of the main code that can be found in https://github.com/cakephp/cakephp

CakePHP Utility Classes This library provides a range of utility classes that are used throughout the CakePHP framework What's in the toolbox? Hash A

CakePHP 112 Feb 15, 2022
Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

Introduction Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services. It handles almost all of the boilerpl

The Laravel Framework 2.2k Dec 31, 2022
Stripe Payments for Magento 2

Magento 2 Stripe Integration Accept credit card payments through the Stripe payment gateway. Supports Magento Instant Purchase for One Click Checkout

Patrick McLain 45 Jul 22, 2022
Ratings and reviews for the Laravel's Eloquent models ⭐⭐⭐⭐⭐

Laravel Reviews Ratings and reviews for the Laravel's Eloquent models Users will be able to rate and review the reviewable models. Then these reviews

Mohamed Ali Tavasoli 31 Dec 4, 2022
Easily add sub domains to your CakePHP application using route prefixes

Easily add sub domains to your CakePHP application using route prefixes. Based on code created by chinpei215.

multidimension.al 4 Feb 28, 2019
The swiss army knife for Magento developers, sysadmins and devops. The tool provides a huge set of well tested command line commands which save hours of work time. All commands are extendable by a module API.

netz98 magerun CLI tools for Magento 2 The n98 magerun cli tools provides some handy tools to work with Magento from command line. Build Status Latest

netz98 758 Dec 28, 2022
Library download currency rate and save in database, It's designed to be extended by any available data source.

Library download currency rate and save in database, It's designed to be extended by any available data source.

Flexmind. Krzysztof Bielecki 2 Oct 6, 2021
Allow any Discord user to sign in to your website and save their discord user information for later use.

Simple Discord SSO ( Single Sign-On ) Requires at least: 5.0 Tested up to: 5.8.3 Stable tag: 1.0.2 Requires PHP: 7.4 License: GPLv2 or later License U

null 2 Oct 7, 2022
now you can save MentionedMessage in UI

General now you can save MentionedMessage in UI Example: You Chat Hi @MulqiGaming @Friends it will be save Message later to MulqiGaming and Friends Co

MulqiGaming64 3 Aug 9, 2022