highperapp / uuid
High-performance UUID generator library implementing RFC 9562 with optional Rust FFI acceleration
Requires
- php: ^8.3
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpbench/phpbench: ^1.2
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.0
Suggests
- ext-bcmath: For arbitrary precision arithmetic fallback
- ext-ffi: For Rust FFI acceleration
- ext-gmp: For improved performance on 32-bit systems
- ext-openssl: For additional entropy sources
- amphp/amp: For async UUID generation
- amphp/parallel: For concurrent UUID generation
- revolt/event-loop: For async UUID generation
This package is auto-updated.
Last update: 2025-07-04 02:37:01 UTC
README
A high-performance UUID generator library implementing RFC 9562 with support for UUIDv1-v8, featuring optional Rust FFI acceleration, async/sync compatibility, and high-concurrency collision prevention.
Features
- ✅ Complete RFC 9562 Support: UUIDv1, v3, v4, v5, v6, v7, v8
- ⚡ High Performance: Optional Rust FFI acceleration
- 🔄 Async/Sync Compatible: Works with both paradigms seamlessly
- 🚀 Concurrency Support: RevoltPHP, AmphpV3, Parallel integration
- 🛡️ Collision Prevention: Advanced mechanisms for high-throughput scenarios
- 🔧 Configurable: Multiple RNG providers and performance options
- 📦 Zero Dependencies: Pure PHP fallback when FFI unavailable
- ✅ PHP 8.3+ Compatible: Supports PHP 8.3 and later versions
Installation
composer require highperapp/uuid
Optional: Rust FFI Acceleration
For maximum performance, you can enable Rust FFI acceleration which can improve UUID generation speed by up to 10x.
Prerequisites
-
Install PHP FFI Extension (required for Rust acceleration):
# Ubuntu/Debian sudo apt update sudo apt install php8.3-ffi php8.3-dev # CentOS/RHEL/Fedora sudo yum install php-ffi php-devel # or for newer versions: sudo dnf install php-ffi php-devel # macOS (with Homebrew) brew install php # FFI is usually included in modern PHP builds # Windows # Enable FFI in php.ini by uncommenting: # extension=ffi
-
Verify FFI Installation:
php -m | grep ffi # Should output: ffi # Test FFI functionality php -r "echo extension_loaded('ffi') ? 'FFI enabled' : 'FFI not available';"
-
Install Rust (if not already installed):
# Using rustup (recommended) curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source $HOME/.cargo/env # Or using your system package manager # Ubuntu/Debian: sudo apt install rustc cargo # macOS: brew install rust # Windows: Download from https://rustup.rs/
-
Verify Installation:
rustc --version cargo --version
Build the Rust Library
cd rust
cargo build --release
The compiled library will be available at rust/target/release/libuuid_ffi.so
(Linux/macOS) or rust/target/release/uuid_ffi.dll
(Windows).
Troubleshooting FFI Issues
If you encounter FFI-related errors:
-
FFI Not Available:
# Check if FFI is installed php -m | grep ffi # Check PHP configuration php --ini | grep "Configuration File" # Enable FFI in php.ini echo "extension=ffi" | sudo tee -a /etc/php/8.3/cli/php.ini
-
FFI Preloading Issues:
# Set FFI preload in php.ini (optional for better performance) echo "ffi.preload=" | sudo tee -a /etc/php/8.3/cli/php.ini
-
Permission Issues:
# Ensure the compiled library has proper permissions chmod +x rust/target/release/libuuid_ffi.so
-
Library Path Issues:
// Test FFI with absolute path $ffi = FFI::cdef("", __DIR__ . "/rust/target/release/libuuid_ffi.so");
Development vs Production
- Development: The library automatically falls back to pure PHP if Rust FFI is unavailable
- Production: For optimal performance, ensure both FFI extension and Rust library are available
- CI/CD: Add both FFI installation and Rust build steps to your deployment pipeline
- Docker: Include FFI in your PHP Docker image and build Rust during image creation
Quick Start
use HighPerApp\HighPer\Uuid\Core\UuidFactory; // Generate UUIDs $uuid4 = UuidFactory::v4(); // Random UUID $uuid7 = UuidFactory::v7(); // Timestamp-based UUID (recommended) $uuid1 = UuidFactory::v1(); // Legacy timestamp + MAC // Name-based UUIDs $uuid3 = UuidFactory::v3(UuidFactory::NAMESPACE_DNS, 'example.com'); $uuid5 = UuidFactory::v5(UuidFactory::NAMESPACE_DNS, 'example.com'); // Convert and validate $uuid = UuidFactory::fromString('550e8400-e29b-41d4-a716-446655440000'); $isValid = UuidFactory::isValid($uuid->toString()); echo $uuid->toString(); // 550e8400-e29b-41d4-a716-446655440000 echo $uuid->getVersion(); // 4
UUID Versions
UUIDv1 - Timestamp + MAC Address
$uuid = UuidFactory::v1(); echo $uuid->getTimestamp(); // Gregorian timestamp echo $uuid->getNode(); // MAC address (or random)
UUIDv3 - MD5 Name-based
$uuid = UuidFactory::v3Dns('example.com'); // Always generates the same UUID for the same input
UUIDv4 - Random
$uuid = UuidFactory::v4(); // Cryptographically random
UUIDv5 - SHA-1 Name-based
$uuid = UuidFactory::v5Url('https://example.com'); // Always generates the same UUID for the same input
UUIDv6 - Reordered Timestamp
$uuid = UuidFactory::v6(); // Like v1 but with better database locality
UUIDv7 - Unix Timestamp (Recommended)
$uuid = UuidFactory::v7(); // Best for new applications - sortable and efficient
UUIDv8 - Custom Format
$uuid = UuidFactory::v8([ 'custom_fields' => [ 'timestamp' => time(), 'counter' => 123 ] ]);
Performance Configuration
High Performance Setup
use HighPerApp\HighPer\Uuid\Core\Configuration; use HighPerApp\HighPer\Uuid\Core\UuidFactory; $config = Configuration::highPerformance(); UuidFactory::configure($config); // Now all UUID generation uses Rust FFI when available $uuid = UuidFactory::v4(); // Uses Rust acceleration
Custom Configuration
$config = Configuration::default() ->setDefaultVersion(7) ->setRandomProvider('rust') ->enableFFI(true) ->setMaxConcurrentWorkers(8); UuidFactory::configure($config);
Async/Concurrent Generation
Async Generation
use HighPerApp\HighPer\Uuid\Async\AsyncUuidFactory; // Single async UUID $uuid = AsyncUuidFactory::v4Async()->await(); // Batch generation $uuids = AsyncUuidFactory::generateBatch(1000, 4)->await(); // Concurrent batch (using worker processes) $uuids = AsyncUuidFactory::generateConcurrentBatch(10000, 4, 8)->await();
High-Throughput Scenarios
use HighPerApp\HighPer\Uuid\Async\ConcurrentGenerator; $generator = new ConcurrentGenerator(8); // 8 worker processes $uuids = $generator->generateConcurrent(100000, 4); // Generates 100,000 UUIDs across 8 processes
Pipeline Processing
use HighPerApp\HighPer\Uuid\Async\AsyncUuidFactory; $pipeline = AsyncUuidFactory::generatePipeline(10000, 7); foreach ($pipeline as $uuid) { // Process each UUID as it's generated echo $uuid->toString() . "\n"; }
Random Number Providers
use HighPerApp\HighPer\Uuid\RandomProvider\RandomProviderFactory; // Available providers $providers = RandomProviderFactory::getAvailableProviders(); // ['secure', 'openssl', 'rust', 'pseudo'] // Create specific provider $provider = RandomProviderFactory::create('rust'); $uuid = UuidFactory::v4($provider); // Benchmark providers $results = RandomProviderFactory::benchmark('rust', 1000);
Collision Prevention
The library includes advanced collision prevention mechanisms:
use HighPerApp\HighPer\Uuid\Concurrency\CollisionPrevention; // Enable collision detection $config = Configuration::default() ->enableCollisionPrevention(true); UuidFactory::configure($config); // The library automatically handles: // - Timestamp collisions // - High-frequency generation // - Multi-process safety // - Sequence management
Benchmarking
Run performance tests to validate performance on your system:
# Run built-in benchmarks (requires PHPBench) vendor/bin/phpbench run benchmarks --report=default # Quick performance test php -r " require 'vendor/autoload.php'; use HighPerApp\HighPer\Uuid\Core\UuidFactory; \$start = microtime(true); for (\$i = 0; \$i < 10000; \$i++) { UuidFactory::v4(); } \$duration = microtime(true) - \$start; echo 'Generated ' . number_format(10000 / \$duration) . ' UUIDs/second\n'; "
Expected Performance Ranges
- Development environment: 300,000 - 600,000 UUIDs/second
- Production environment: 600,000 - 900,000 UUIDs/second
- With Rust FFI: 1,000,000+ UUIDs/second
- High-concurrency scenarios: 400,000 - 800,000 UUIDs/second
Performance depends on:
- CPU speed and architecture
- PHP version and configuration
- Available memory
- FFI extension availability
- Rust library compilation
Integration Examples
Laravel
// In a Laravel service provider use HighPerApp\HighPer\Uuid\Core\Configuration; use HighPerApp\HighPer\Uuid\Core\UuidFactory; public function boot() { UuidFactory::configure(Configuration::highPerformance()); } // In your models protected $keyType = 'string'; public $incrementing = false; protected static function boot() { parent::boot(); static::creating(function ($model) { if (empty($model->id)) { $model->id = UuidFactory::v7()->toString(); } }); }
Symfony
// services.yaml services: HighPerApp\HighPer\Uuid\Core\Configuration: factory: ['HighPerApp\HighPer\Uuid\Core\Configuration', 'highPerformance'] uuid_factory: class: HighPerApp\HighPer\Uuid\Core\UuidFactory calls: - configure: ['@HighPerApp\HighPer\Uuid\Core\Configuration']
Database Storage
-- MySQL CREATE TABLE users ( id BINARY(16) PRIMARY KEY, uuid_string CHAR(36) GENERATED ALWAYS AS ( CONCAT( HEX(SUBSTR(id, 1, 4)), '-', HEX(SUBSTR(id, 5, 2)), '-', HEX(SUBSTR(id, 7, 2)), '-', HEX(SUBSTR(id, 9, 2)), '-', HEX(SUBSTR(id, 11, 6)) ) ) STORED, name VARCHAR(255) ); -- PostgreSQL CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE TABLE users ( id UUID PRIMARY KEY, name VARCHAR(255) );
Performance Characteristics
Version | Performance | Use Case | Sortable | Collision Risk |
---|---|---|---|---|
v1 | High | Legacy systems | No | Very Low |
v3 | Medium | Name-based, reproducible | No | None |
v4 | High | General purpose | No | Negligible |
v5 | Medium | Name-based, reproducible | No | None |
v6 | High | Sortable timestamp | Yes | Very Low |
v7 | Highest | Recommended for new apps | Yes | Very Low |
v8 | Variable | Custom implementations | Variable | Variable |
Throughput Benchmarks
Benchmarks measured on PHP 8.3.6, Linux x86_64. Performance may vary based on hardware and configuration.
Configuration | UUIDs/second | Memory/UUID | Notes |
---|---|---|---|
Pure PHP v4 | ~600,000-900,000 | <100 bytes | Actual performance exceeds estimates |
Pure PHP v7 | ~700,000-900,000 | <100 bytes | Recommended for new applications |
Pure PHP v1 | ~600,000 | <100 bytes | Legacy timestamp-based |
Pure PHP v3/v5 | ~850,000-900,000 | <100 bytes | Name-based UUIDs (cached) |
Rust FFI v4 | ~1,000,000+ | <50 bytes | Requires FFI extension + Rust build |
Rust FFI v7 | ~1,200,000+ | <50 bytes | Optimal for high-throughput scenarios |
Concurrent v4 | ~400,000-800,000 | Variable | Depends on worker count and overhead |
Memory Usage Notes:
- Memory per UUID is minimal in normal usage due to PHP's garbage collection
- Bulk operations (10,000+ UUIDs) may use ~100-200 bytes per UUID temporarily
- String representation adds ~36 bytes per UUID when stored
- Memory usage scales linearly with batch size
Configuration Options
$config = new Configuration(); // Version settings $config->setDefaultVersion(7); // Default: 7 // Performance settings $config->enableFFI(true); // Default: true $config->preferRustFFI(true); // Default: true $config->setMaxConcurrentWorkers(8); // Default: 4 // Security settings $config->setRandomProvider('secure'); // Default: 'secure' $config->enableCollisionPrevention(true); // Default: true // Timestamp settings $config->enableMonotonicTimestamp(true); // Default: true $config->setTimestampPrecision(1000); // microseconds // Namespaces $config->addNamespace('custom', 'your-namespace-uuid');
Error Handling
use HighPerApp\HighPer\Uuid\Exception\GenerationException; use HighPerApp\HighPer\Uuid\Exception\ValidationException; use HighPerApp\HighPer\Uuid\Exception\ConfigurationException; try { $uuid = UuidFactory::v3('invalid-namespace', 'name'); } catch (ValidationException $e) { // Handle validation errors } try { $uuid = UuidFactory::generate(99); // Invalid version } catch (GenerationException $e) { // Handle generation errors }
Development Setup
Prerequisites
-
PHP 8.3+ with extensions:
# Check required extensions php -m | grep -E "(ffi|openssl|json)" # Install missing extensions (Ubuntu/Debian) sudo apt install php8.3-ffi php8.3-openssl php8.3-json php8.3-dev # CentOS/RHEL/Fedora sudo yum install php-ffi php-openssl php-json php-devel # macOS (with Homebrew) brew install php # Verify FFI is working php -r "echo extension_loaded('ffi') ? 'FFI: ✓' : 'FFI: ✗';"
-
Composer (for PHP dependencies):
composer install
-
Rust (optional, for FFI acceleration):
# Install Rust if not already installed curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source $HOME/.cargo/env # Build the Rust library cd rust && cargo build --release # Verify Rust FFI library is built ls -la rust/target/release/libuuid_ffi.so
Development Workflow
# 1. Install dependencies composer install # 2. (Optional) Build Rust FFI for performance cd rust && cargo build --release && cd .. # 3. Run tests vendor/bin/phpunit # 4. Run static analysis vendor/bin/phpstan analyse
Testing
# Run tests vendor/bin/phpunit # Run with coverage vendor/bin/phpunit --coverage-html coverage # Run benchmarks vendor/bin/phpbench run benchmarks --report=default # Static analysis vendor/bin/phpstan analyse
Requirements
- PHP 8.3 or higher
ext-ffi
(required for Rust FFI acceleration)ext-openssl
(required for secure random generation)ext-json
(required for configuration)revolt/event-loop
^1.0amphp/amp
^3.0amphp/parallel
^2.0
FFI Configuration
For production environments, consider adding these settings to your php.ini
:
# Enable FFI extension extension=ffi # Optional: Preload FFI for better performance ; ffi.preload= # Optional: Set FFI scope (default is "preload") ; ffi.enable=preload
Contributing
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
MIT License. See LICENSE for details.
Changelog
v1.0.0
- Initial release
- Complete RFC 9562 implementation
- Rust FFI acceleration
- Async/concurrent support
- Comprehensive test suite