Model Hashids
Model Hashids encodes and decodes a model's primary key on demand. The hashid is not stored in the database, so queries still use the model's primary-key column.
Installation
composer require friendsofhyperf/model-hashidsThe package requires hashids/hashids and Hyperf 3.2's config, database, and stringable components. Publish the configuration file only when you need to customize the hashid settings:
php bin/hyperf.php vendor:publish friendsofhyperf/model-hashidsSetup
Add HasHashid to a model. Add HashidRouting as well if implicit route binding should use hashids:
use FriendsOfHyperf\ModelHashids\Concerns\HasHashid;
use FriendsOfHyperf\ModelHashids\Concerns\HashidRouting;
use Hyperf\Database\Model\Model;
class Item extends Model
{
use HasHashid;
use HashidRouting;
}Configuration
The published file is config/autoload/hashids.php. default selects a connection, and each connection accepts salt, length, and alphabet:
return [
'default' => 'main',
'connections' => [
'main' => [
'salt' => '',
'length' => 0,
'alphabet' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890',
],
],
];Without a published configuration, the component uses the main connection, an empty salt, a minimum length of 0, and the alphabet shown above.
To select a different connection for one model, override the protected getHashidsConnection() method:
class Item extends Model
{
use HasHashid;
protected function getHashidsConnection()
{
return 'alternative';
}
}Usage
Encoding and Queries
// Encode the model's primary key.
$item->hashid();
// Access the same value through the hashid accessor.
$item->hashid;
// Encode an ID or decode a valid hashid.
$item->idToHashid($id);
$item->hashidToId($hashid);
// Add a primary-key constraint decoded from the hashid.
Item::query()->byHashid($hashid)->get();
// Return the first matching model, null, or throw ModelNotFoundException.
Item::findByHashid($hashid);
Item::findByHashidOrFail($hashid);hashidToId() returns the first ID decoded by hashids/hashids; pass it a valid hashid created with the same connection settings.
Serializing the Hashid
The hashid accessor is not appended automatically. Add it to the model's $appends property:
class Item extends Model
{
use HasHashid;
protected $appends = ['hashid'];
}Alternatively, append it only when needed:
return $item->append('hashid')->toJson();Implicit Route Binding
HashidRouting makes the default route key the model's hashid and resolves it through byHashid:
Route::get('/items/{item}', function (Item $item) {
return $item;
});For a route that explicitly names another field, resolution is delegated to the model's parent implementation:
Route::get('/items/{item:slug}', function (Item $item) {
return $item;
});You can also make another field the default while still selecting hashid on a specific route:
class Item extends Model
{
use HasHashid;
use HashidRouting;
public function getRouteKeyName()
{
return 'slug';
}
public function getRouteKey()
{
return $this->slug;
}
}Route::get('/items/{item:hashid}', function (Item $item) {
return $item;
});