Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Hashids Bundle Laravel Package

philetaylor/hashids-bundle

Symfony bundle integrating Hashids to obfuscate numeric IDs as short, unique, non-sequential strings. Provides services and Twig filters for encoding and decoding IDs with configurable salt, length, and alphabet.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package — the first decision is whether you're actually on Symfony. If you're a Laravel developer looking at this repo, note that Laravel already has first-party community options (vinkla/hashids), and this bundle gives you nothing on Laravel. Assume the rest of this assessment targets a Symfony app that wants short, obfuscated public IDs (e.g. /orders/x7Kp2m instead of /orders/18432).

Minimal steps:

  1. composer require philetaylor/hashids-bundle (it wraps hashids/hashids).
  2. Register the bundle in config/bundles.php — with 1 star and a 2022 release, expect the older Bundle class registration style, not a modern Flex recipe. There is no Flex recipe, so you will hand-write the config.
  3. Create config/packages/hashids.yaml (verify the exact root key against the bundle's DependencyInjection/Configuration.php, since docs are thin):
# config/packages/philetaylor_hashids.yaml
philetaylor_hashids:
    salt: '%env(HASHIDS_SALT)%'
    min_hash_length: 8
    alphabet: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
  1. Put a long random value in HASHIDS_SALT (bin/console secrets:set HASHIDS_SALT or .env.local). Never commit a production salt.
  2. Confirm wiring with bin/console debug:container hashids (or whatever the service ID actually is — inspect Resources/config/services.xml in the bundle).

First use case: replace a raw auto-increment ID in a route with an encoded token, and decode it back in the controller. That's 90% of what this bundle is for; anything more elaborate (Twig filters, Doctrine integration) is usually your own glue code rather than something the bundle ships.

Implementation Patterns

Controller injection. Type-hint the Hashids service (or the bundle's alias) into your action, or constructor-inject it into a service. If the bundle doesn't autowire under a friendly alias, add one in config/services.yaml:

services:
    Hashids\Hashids:
        alias: hashids   # confirm actual service id first

Route-level decoding. Prefer decoding in one place rather than scattering decode() calls. A small HashidParamConverter (or a custom route requirement + listener) keeps controllers clean:

public function show(string $publicId, Hashids $hashids): Response
{
    $ids = $hashids->decode($publicId);   // returns [] on garbage
    if ($ids === []) {
        throw $this->createNotFoundException();
    }
    return $this->render('order/show.html.twig', [
        'order' => $this->orders->find($ids[0]),
    ]);
}

Exposing the public ID on entities. Don't recalculate in templates. Either:

  • add a getPublicId(): string method on the entity that calls a statically-injected encoder (ugly but common), or
  • better, map it at the boundary: a Doctrine postLoad listener that stamps a non-persisted $publicId property, or a serializer normalizer that rewrites id → encoded form on output and decodes on input.

Twig. The bundle may or may not register a filter. If not, add a tiny extension:

public function hashid(int $id): string { return $this->hashids->encode($id); }

Then {{ path('order_show', {publicId: order.id|hashid}) }}.

Symfony Form / API Platform. Use a data transformer (Form) or an input DTO + denormalizer (API Platform) so encoded IDs are decoded once at the edge and your domain layer only ever sees integers. This is the pattern that scales; sprinkling decode() in controllers does not.

Multiple salt domains. If you need stable-per-tenant or per-entity-type tokens, instantiate additional new Hashids($salt_for_tenant, 8) directly — the bundle gives you one configured instance, not a factory. Keep the bundle for the "default" case.

Gotchas and Tips

  • The salt is the whole security model. Change it in production and every previously shared link breaks silently (decode returns [], your code 404s). Treat rotation as a migration, not a config tweak.
  • Hashids is obfuscation, not encryption. Anyone can decode a token if they guess your alphabet/length; it deters scraping and sequential-ID enumeration, nothing more. Never encode secrets or use it as an authz check — still enforce ownership on the decoded ID.
  • Alphabet constraints. Minimum 16 unique characters, no spaces. min_hash_length only pads output; it does not add entropy. Two configs with different salts/lengths produce non-interoperable tokens — keep dev/staging/prod aligned or you'll chase phantom decode failures.
  • Degenerate inputs. encode(0) and empty values behave surprisingly ('' in, [] out on decode). Guard decode() for the [] case explicitly and never assume index 0 exists.
  • Big integers. Hashids works in the 64-bit integer range; BIGINT UNSIGNED IDs near the top of the range, or UUIDs, are out of scope. If you're on UUID PKs this package is the wrong tool.
  • Maintenance risk is the headline. 1 star, 0 dependents, last release Sep 2022. There is essentially no upstream support. Pin the exact version in composer.json, and seriously consider skipping the bundle: composer require hashids/hashids and one service definition in services.yaml reproduces the entire feature with zero third-party Symfony coupling and a maintained library underneath.
  • Symfony version compatibility. A 2022 bundle may not declare support for Symfony 7, may use deprecated container APIs, or may not be autowirable. Check composer show philetaylor/hashids-bundle and the bundle's composer.json constraints before adopting; bin/console debug:container and debug:config are your fastest diagnosis tools when the service doesn't appear.
  • Extension points. Realistically two: override the service definition/alias in your app config, or set the salt via an env var. There's no documented plugin surface, so don't plan architecture around extending this bundle — plan around the underlying hashids/hashids API instead, which is stable and well-documented.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console