gryfoss/doctrine-random-id-generator

Generates a random ID instead of using autoincrementation.

Installs: 32

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/gryfoss/doctrine-random-id-generator

v2.0.0 2025-10-10 15:12 UTC

This package is auto-updated.

Last update: 2025-10-10 15:26:20 UTC


README

Tests Coverage PHP Symfony

A robust Doctrine ORM ID generator that creates random unique IDs instead of using auto-incrementation. v2.0.0 adds string ID support!

✨ Features

  • 🎲 Random ID Generation: Generates cryptographically secure random integer and string IDs
  • πŸ†• String ID Support (v2.0.0): Generate random alphanumeric, hexadecimal, or custom character string IDs
  • πŸ”§ Configurable Options: Customize ranges, lengths, character sets per entity
  • ⚑ Collision Prevention: Automatic uniqueness checking with configurable retry attempts
  • πŸ›‘οΈ Type Safety: Full PHP 8.2+ type declarations and readonly properties
  • πŸ§ͺ 100% Test Coverage: Comprehensive unit and functional test suites
  • 🐳 Docker Ready: Complete functional testing with Symfony + MariaDB
  • πŸ“¦ Symfony Integration: Proper service container configuration

πŸš€ Installation

composer require gryfoss/doctrine-random-id-generator

πŸ’‘ Usage Examples

Integer IDs (Existing)

<?php

use Doctrine\ORM\Mapping as ORM;
use GryfOSS\Dbal\RandomIdGenerator;

#[ORM\Entity]
class Product
{
    #[ORM\Id]
    #[ORM\Column(type: 'integer')]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: RandomIdGenerator::class)]
    private int $id; // Generates: 742856

    // ... other properties
}

String IDs (NEW in v2.0.0)

<?php

use Doctrine\ORM\Mapping as ORM;
use GryfOSS\Dbal\RandomStringIdGenerator;

#[ORM\Entity]
class Article
{
    #[ORM\Id]
    #[ORM\Column(type: 'string', length: 10)]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: 'app.random_string_id_generator.default')]
    private string $id; // Generates: "Kj8mN3qR9X"

    // ... other properties
}

#[ORM\Entity]
class Order
{
    #[ORM\Id]
    #[ORM\Column(type: 'string', length: 16)]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: 'app.random_string_id_generator.hex')]
    private string $id; // Generates: "A1B2C3D4E5F67890"

    // ... other properties
}

Service Configuration (Symfony)

# config/services.yaml
services:
    # Integer ID Generators
    app.random_id_generator.default:
        class: GryfOSS\Dbal\RandomIdGenerator
        public: true

    app.random_id_generator.custom:
        class: GryfOSS\Dbal\RandomIdGenerator
        arguments:
            $minId: 1000
            $maxId: 9999
            $maxAttempts: 15
        public: true

    # String ID Generators (NEW in v2.0.0)
    app.random_string_id_generator.default:
        class: GryfOSS\Dbal\RandomStringIdGenerator
        public: true
        # Default: 10-char alphanumeric, 10 attempts

    app.random_string_id_generator.hex:
        class: GryfOSS\Dbal\RandomStringIdGenerator
        arguments:
            $symbols: '0123456789ABCDEF'
            $length: 16
            $maxAttempts: 20
        public: true

Entity with Service Reference

#[ORM\Entity]
class Customer
{
    #[ORM\Id]
    #[ORM\Column(type: 'integer')]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: 'app.random_id_generator.custom')]
    private int $id;
}

🎯 Use Cases

Integer IDs

  • πŸ›‘οΈ Security: Prevent ID enumeration attacks
  • πŸ•΅οΈ Privacy: Hide business metrics from sequential IDs
  • 🌐 Distributed Systems: Avoid ID conflicts across services
  • πŸ§ͺ Load Testing: Predictable ranges for testing scenarios

String IDs (NEW in v2.0.0)

  • πŸ” API Keys: Secure, non-sequential API identifiers
  • 🎫 Tokens: Session tokens, verification codes, access keys
  • πŸ“± User-Friendly IDs: Readable IDs for public-facing references
  • 🏷️ Order Numbers: E-commerce order codes without sequential exposure
  • 🎲 Game IDs: Lobby codes, match identifiers, player tags

πŸ†• String Generator Guide (v2.0.0)

Quick Start with String IDs

The RandomStringIdGenerator creates cryptographically secure random string IDs with customizable length and character sets.

1. Basic Setup

Add the string generator service to your config/services.yaml:

services:
    app.random_string_id_generator.default:
        class: GryfOSS\Dbal\RandomStringIdGenerator
        public: true
        # Default: 10-char alphanumeric (0-9a-zA-Z), 10 attempts

2. Entity Configuration

<?php

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
class Article
{
    #[ORM\Id]
    #[ORM\Column(type: 'string', length: 10)]  // Match your generator's length
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: 'app.random_string_id_generator.default')]
    private string $id;

    // ... other properties
}

3. Generated Results

// Example generated IDs:
$article1->getId(); // "Kj8mN3qR9X"
$article2->getId(); // "7pQs2vB4Fn"
$article3->getId(); // "Xm9cLa6Wz8"

Advanced String Generator Configurations

Hexadecimal IDs (Perfect for Order Numbers)

services:
    app.random_string_id_generator.hex:
        class: GryfOSS\Dbal\RandomStringIdGenerator
        arguments:
            $symbols: '0123456789ABCDEF'
            $length: 16
            $maxAttempts: 20
        public: true
#[ORM\Entity]
class Order
{
    #[ORM\Id]
    #[ORM\Column(type: 'string', length: 16)]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: 'app.random_string_id_generator.hex')]
    private string $id; // Generates: "A1B2C3D4E5F67890"
}

Short Codes (API Keys, Tokens)

services:
    app.random_string_id_generator.short:
        class: GryfOSS\Dbal\RandomStringIdGenerator
        arguments:
            $symbols: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'  # Uppercase only
            $length: 8
            $maxAttempts: 15
        public: true
#[ORM\Entity]
class ApiKey
{
    #[ORM\Id]
    #[ORM\Column(type: 'string', length: 8)]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: 'app.random_string_id_generator.short')]
    private string $id; // Generates: "K7M9P2X4"
}

Custom Character Sets

services:
    app.random_string_id_generator.custom:
        class: GryfOSS\Dbal\RandomStringIdGenerator
        arguments:
            $symbols: '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'  # No confusing chars (0,1,I,O)
            $length: 12
            $maxAttempts: 10
        public: true

String Generator Parameters

Parameter Type Default Range Description
$symbols string 0-9a-zA-Z Any non-empty string Characters used for ID generation
$length int 10 2-254 Length of generated string IDs
$maxAttempts int 10 1+ Max generation attempts before exception

Common Character Sets

# Alphanumeric (default)
$symbols: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

# Hexadecimal (uppercase)
$symbols: '0123456789ABCDEF'

# Hexadecimal (lowercase)
$symbols: '0123456789abcdef'

# Numbers only
$symbols: '0123456789'

# Letters only (mixed case)
$symbols: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

# URL-safe base64-like
$symbols: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'

# Human-friendly (no confusing characters)
$symbols: '23456789ABCDEFGHJKLMNPQRSTUVWXYZ'  # No 0,1,I,O

Best Practices for String IDs

1. Choose Appropriate Length

  • Short codes (6-8 chars): Temporary tokens, verification codes
  • Medium codes (10-12 chars): User-facing IDs, order numbers
  • Long codes (16+ chars): API keys, security tokens

2. Select Character Sets Wisely

  • Hexadecimal: Technical systems, integrations
  • Alphanumeric: General purpose, good balance of length/readability
  • Human-friendly: Public-facing codes (avoid 0/O, 1/I confusion)

3. Consider Database Collation

-- Case-sensitive collation for string IDs
ALTER TABLE articles MODIFY COLUMN id VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

4. Index Performance

-- String IDs benefit from explicit indexes
CREATE INDEX idx_article_id ON articles(id);

Error Handling

The string generator validates parameters and provides clear error messages:

// Length validation
new RandomStringIdGenerator('ABC', 1);     // Exception: Length must be >= 2
new RandomStringIdGenerator('ABC', 255);   // Exception: Length must be <= 254

// Symbol validation
new RandomStringIdGenerator('', 10);       // Exception: Symbols cannot be empty

// Generation failure
// If max attempts reached, throws RuntimeException with details

πŸ”§ Configuration Options

RandomIdGenerator (Integer IDs)

Parameter Default Description
$minId 100000 Minimum ID value (inclusive)
$maxId 999999 Maximum ID value (inclusive)
$maxAttempts 10 Maximum generation attempts before throwing exception

RandomStringIdGenerator (String IDs)

Parameter Default Description
$symbols 0-9a-zA-Z Character set for ID generation
$length 10 Length of generated string IDs (2-254)
$maxAttempts 10 Maximum generation attempts before throwing exception

⬆️ Upgrading to v2.0.0

Fully Backward Compatible

Good news! v2.0.0 is 100% backward compatible with v1.x. Your existing integer ID generators will continue working without any changes.

# Update to v2.0.0
composer update gryfoss/doctrine-random-id-generator

Optional: Add String ID Support

To start using string IDs in new entities, add the string generator services:

# config/services.yaml - ADD these new services
services:
    # Your existing integer generators continue working unchanged
    app.random_id_generator.default:
        class: GryfOSS\Dbal\RandomIdGenerator
        public: true

    # NEW: Add string generators for new entities
    app.random_string_id_generator.default:
        class: GryfOSS\Dbal\RandomStringIdGenerator
        public: true

    app.random_string_id_generator.hex:
        class: GryfOSS\Dbal\RandomStringIdGenerator
        arguments:
            $symbols: '0123456789ABCDEF'
            $length: 16
            $maxAttempts: 20
        public: true

Migration Checklist

  • βœ… Existing Entities: No changes needed, keep working as-is
  • βœ… Existing Services: Continue using your current configuration
  • βœ… New Entities: Optionally use string IDs with new service references
  • βœ… Tests: Run your existing test suite - everything should pass
  • βœ… Documentation: Review new string ID examples if adopting them

πŸ“š Documentation

πŸ§ͺ Testing

Unit Tests (100% Coverage)

# Run unit tests
composer test

# Generate coverage report
composer test:coverage

# View coverage
open tests/coverage.html/index.html

Functional Tests (Docker + Symfony + MariaDB)

# Run complete functional test suite
cd functional-tests
./run-functional-tests.sh

# Test specific components
./run-functional-tests.sh setup      # Environment setup
./run-functional-tests.sh test-only  # Tests only
./run-functional-tests.sh cleanup    # Cleanup

Local Workflow Testing

# Test all GitHub workflow components locally
./test-workflow.sh

πŸ”„ GitHub Actions

The project includes a comprehensive GitHub Actions workflow that:

  • βœ… Runs unit tests with 100% coverage verification
  • βœ… Executes functional tests in Docker environment
  • βœ… Tests multiple PHP versions (8.2, 8.3)
  • βœ… Tests multiple Symfony versions (7.0., 7.1.)
  • βœ… Performs security scans for vulnerabilities
  • βœ… Validates code quality with PSR-12 compliance

The workflow automatically runs on pushes and pull requests to main and develop branches.

πŸ“Š Test Results (v2.0.0)

Unit Tests

  • Tests: 50+ tests (16 integer + 34 string) with 420+ assertions
  • Coverage: 100% lines, methods, and classes for both generators
  • Performance: < 200ms execution time for complete test suite

Functional Tests

  • Environment: Docker + Symfony 7+ + MariaDB 10.11
  • Scenarios: Integer IDs, string IDs, custom configurations, large-scale testing
  • Validation: Direct database queries, 40,000+ generated entities
  • String Entities: Articles (alphanumeric), Orders (hexadecimal)

Large-Scale Testing

  • Entity Generation: 10,000+ entities per type (40,000+ total)
  • Memory Management: Optimized batch processing with 512MB PHP limit
  • Performance: Sub-second generation for 1000+ entities
  • Validation: 100% uniqueness verification across all generated IDs

Integration Tests

  • PHP Compatibility: 8.2, 8.3
  • Symfony Compatibility: 7.0., 7.1.
  • Service Container: Proper DI configuration for both integer and string generators

πŸ›‘οΈ Security

  • Cryptographically Secure: Uses random_int() for both integer and string ID generation
  • Collision Prevention: Automatic uniqueness checking with configurable retry mechanisms
  • Attempt Limiting: Prevents infinite loops and DoS scenarios for both generators
  • Input Validation: Parameter validation with clear error messages
  • Type Safety: Full type declarations prevent runtime errors
  • Dependency Scanning: Automated security vulnerability checks

🎯 Production Ready (v2.0.0)

Both RandomIdGenerator and RandomStringIdGenerator are production-ready with:

  • βœ… 100% Test Coverage - Every line of code tested for both generators
  • βœ… Large-Scale Testing - Validated with 40,000+ entity generation
  • βœ… Functional Testing - Real-world Docker + Symfony + MariaDB validation
  • βœ… Multiple PHP/Symfony Versions - Broad compatibility
  • βœ… Comprehensive Documentation - Complete setup guides for both integer and string IDs
  • βœ… CI/CD Pipeline - Automated quality assurance

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Run tests locally: ./test-workflow.sh
  4. Commit changes: git commit -m 'Add amazing feature'
  5. Push to branch: git push origin feature/amazing-feature
  6. Open a Pull Request

All pull requests must pass the GitHub Actions workflow, including 100% test coverage.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ‘₯ Authors

πŸ™ Acknowledgments

  • Doctrine ORM team for the excellent ORM framework
  • Symfony team for the dependency injection container
  • PHPUnit team for the testing framework
  • The PHP community for continuous improvements

Made with ❀️ for the PHP community