UUID and ULID support for CodeIgniter 4 with seamless Model integration.
composer require michalsn/codeigniter4-uuid:^2.0Publish the configuration file:
php spark uuid:publishThis creates app/Config/Uuid.php where you can customize the defaults:
<?php
namespace Config;
use Michalsn\CodeIgniterUuid\Config\Uuid as BaseUuid;
use Michalsn\CodeIgniterUuid\Enums\UuidType;
use Michalsn\CodeIgniterUuid\Enums\UuidVersion;
use Symfony\Component\Uid\Uuid as SymfonyUuid;
class Uuid extends BaseUuid
{
// Default UUID version for generation
public UuidVersion $defaultVersion = UuidVersion::V7;
// Default storage type: STRING (36 chars) or BYTES (16 bytes binary)
public UuidType $defaultType = UuidType::STRING;
// ...
}Use the HasUuid trait to add UUID support to your models:
<?php
namespace App\Models;
use CodeIgniter\Model;
use Michalsn\CodeIgniterUuid\Traits\HasUuid;
class ProjectModel extends Model
{
use HasUuid;
protected $table = 'projects';
protected $primaryKey = 'id';
protected $useAutoIncrement = false; // Required for UUID primary keys
protected $returnType = 'array';
protected $allowedFields = ['name', 'description'];
// Define UUID fields using casts
protected array $casts = [
'id' => 'uuid',
];
}The trait automatically:
- Generates UUIDs for the primary key on insert
- Handles UUID conversion for
find(),update(), anddelete()operations - Supports both single and batch inserts
Note
If you already use initialize() method in your model, then you have to add $this->initUuid() call inside this method to make the UUID package work.
The uuid cast accepts optional parameters for version and storage type:
protected array $casts = [
// Use defaults from config
'id' => 'uuid',
// Specify version only
'id' => 'uuid[v4]',
// Specify version and storage type
'id' => 'uuid[v7,bytes]',
// Use default version with specific storage type
'id' => 'uuid[,bytes]',
];You can use UUIDs on any field, not just primary keys:
class OrderModel extends Model
{
use HasUuid;
protected $table = 'orders';
protected $primaryKey = 'id';
protected $useAutoIncrement = true; // Regular auto-increment primary key
protected $allowedFields = ['tracking_id', 'customer_id', 'total'];
protected array $casts = [
'tracking_id' => 'uuid[v4]',
];
}UUIDs are only auto-generated for the primary key field. For other fields, you must provide the value:
$order = [
'tracking_id' => service('uuid')->uuid4()->toRfc4122(),
'customer_id' => 123,
'total' => 99.99,
];
$model->insert($order);Stores UUIDs as 36-character strings (e.g., 550e8400-e29b-41d4-a716-446655440000).
CREATE TABLE projects (
id CHAR(36) NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL
);Stores UUIDs as 16-byte binary for better performance and smaller storage footprint, but at the cost of readability.
protected array $casts = [
'id' => 'uuid[v7,bytes]',
];-- MySQL
CREATE TABLE projects (
id BINARY(16) NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
-- PostgreSQL
CREATE TABLE projects (
id BYTEA NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL
);With binary storage:
- The model returns UUIDs as RFC4122 strings (human-readable)
- Internally converts to binary for database operations
- Supports MySQL, PostgreSQL, SQLite3, Oracle, and SQL Server
Generate UUIDs using the service:
// Convenience methods (recommended)
$uuid = service('uuid')->uuid4();
$uuid = service('uuid')->uuid7();
$ulid = service('uuid')->ulid();
// Or use generate() with string parameter
$uuid = service('uuid')->generate('v4');
$uuid = service('uuid')->generate('v7');
// Or use generate() with enum for type safety
use Michalsn\CodeIgniterUuid\Enums\UuidVersion;
$uuid = service('uuid')->generate(UuidVersion::V4);
$uuid = service('uuid')->generate(UuidVersion::ULID);
// Generate using default version from config
$uuid = service('uuid')->generate();Working with UUIDs:
$uuid = service('uuid')->generate('v7');
// Convert to different formats
$uuid->toRfc4122(); // "550e8400-e29b-41d4-a716-446655440000"
$uuid->toBinary(); // 16-byte binary string
$uuid->toBase32(); // Crockford Base32 encoding
$uuid->toBase58(); // Base58 encodingParse existing UUIDs:
// From string (with or without hyphens)
$uuid = service('uuid')->fromString('550e8400-e29b-41d4-a716-446655440000');
$uuid = service('uuid')->fromString('550e8400e29b41d4a716446655440000');
// From ULID string
$ulid = service('uuid')->fromString('01ARZ3NDEKTSV4RRFFQ69G5FAV');
// From unknown format (string or binary)
$uuid = service('uuid')->fromValue($unknownValue);Validate UUIDs:
// Check if a string is a valid UUID or ULID
service('uuid')->isValid('550e8400-e29b-41d4-a716-446655440000'); // true
service('uuid')->isValid('01ARZ3NDEKTSV4RRFFQ69G5FAV'); // true (ULID)
service('uuid')->isValid('not-a-uuid'); // false| Version | Description | Use Case |
|---|---|---|
v1 |
Timestamp + MAC address | Legacy systems |
v3 |
Namespace + name (MD5) | Deterministic UUIDs |
v4 |
Random | General purpose |
v5 |
Namespace + name (SHA1) | Deterministic UUIDs |
v6 |
Timestamp-ordered (reordered v1) | Time-sortable |
v7 |
Timestamp-ordered (Unix epoch) | Recommended - Time-sortable, database-friendly |
ulid |
Universally Unique Lexicographically Sortable Identifier | Time-sortable, shorter string representation |
Recommendation: Use UUID v7 for new projects. It provides:
- Chronological ordering (great for database indexes)
- Better performance than v4 for sorted queries
- Standard UUID format compatibility
- Dependency Change: Switched from
ramsey/uuidtosymfony/uid - UUID v2 Removed: UUID v2 (DCE Security) is no longer supported
- Removed Classes:
UuidModel,UuidEntity,UuidCast(old location) removed - New Trait-Based Approach: Use
HasUuidtrait instead of extendingUuidModel - Type-Safe Versions: Use
UuidVersionandUuidTypeenum instead of string constants
{
"require": {
"michalsn/codeigniter4-uuid": "^2.0"
}
}Run composer update.
Before (v1):
use Michalsn\Uuid\UuidModel;
class ProjectModel extends UuidModel
{
protected $uuidVersion = 'uuid7';
protected $uuidFields = ['id', 'tracking_id'];
}After (v2):
use CodeIgniter\Model;
use Michalsn\CodeIgniterUuid\Traits\HasUuid;
class ProjectModel extends Model
{
use HasUuid;
protected $useAutoIncrement = false;
protected array $casts = [
'id' => 'uuid[v7]',
'tracking_id' => 'uuid[v4]',
];
}Before (v1):
use Michalsn\Uuid\UuidEntity;
class ProjectEntity extends UuidEntity
{
protected $uuids = ['id', 'category_id'];
}After (v2):
Entities no longer need special handling. Use standard CodeIgniter entities - the model's cast handles UUID conversion automatically.
use CodeIgniter\Entity\Entity;
class ProjectEntity extends Entity
{
// No special UUID configuration needed
}Before (v1):
// In model file
public $uuidVersion = 'uuid7';After (v2):
// In config file
use Michalsn\CodeIgniterUuid\Enums\UuidVersion;
public UuidVersion $defaultVersion = UuidVersion::V7;The old Ramsey UUID method names still work for backward compatibility:
// These work (backward compatible)
$uuid->toString(); // alias for toRfc4122()
$uuid->getBytes(); // alias for toBinary()
$uuid->getHex(); // alias for toHex()
// New Symfony UID methods (preferred)
$uuid->toRfc4122();
$uuid->toBinary();
$uuid->toHex();
$uuid->toBase32();
$uuid->toBase58();If you were using UUID v2, you'll need to migrate to a different version (v4 or v7 recommended).
If you need direct access to the underlying Symfony UID object:
$uuid = service('uuid')->uuid7();
$symfonyUuid = $uuid->unwrap(); // Returns Symfony\Component\Uid\UuidV7- ULID Support: Generate and parse ULIDs alongside UUIDs
- SQLite Support: Binary UUID storage now works with SQLite3
- Backward Compatible API: Old Ramsey method names (
toString(),getBytes()) still work
The MIT License (MIT). Please see License File for more information.