pragmarx/random
Cryptographically secure random generator for PHP: create random strings, integers, bytes, hex, and regex-based patterns with options for size, case, prefixes/suffixes, and raw output. Falls back to Faker (if installed) for rich random data like names and dates.
Installation:
composer require pragmarx/random
Add to composer.json if not using autoloading:
"autoload": {
"psr-4": {
"App\\": "app/",
"Pragmarx\\Random\\": "vendor/pragmarx/random/src/"
}
}
Run composer dump-autoload.
First Use Case: Generate a random string (e.g., for API tokens, test data, or seeders):
use Pragmarx\Random\Random;
$random = new Random();
$token = $random->string(32); // Generates a 32-character alphanumeric string
Key Classes:
Random: Core class for generating random strings, numbers, and chars.RandomString: Subclass for string-specific methods (e.g., uuid(), slug()).RandomNumber: Subclass for numeric ranges (e.g., number(1, 100)).Quick Reference:
$random->string(10); // Random alphanumeric string (e.g., "aB3x9KpL2q")
$random->uuid(); // Random UUID (e.g., "550e8400-e29b-41d4-a716-446655440000")
$random->number(1, 100); // Random integer between 1 and 100
$random->boolean(); // Random boolean (true/false)
$random->char(); // Single random character
$random->slug('test string'); // URL-friendly slug (e.g., "test-string")
Test Data Generation:
Use in DatabaseSeeder or factories to populate test databases:
$random = new Random();
User::factory()->count(10)->create(function () use ($random) {
return [
'email' => "user{$random->number(1, 1000)}@example.com",
'password' => $random->string(12),
];
});
API Tokens and IDs: Generate unique tokens for authentication or temporary resources:
$token = $random->string(64); // Store in DB for user sessions
$tempId = $random->uuid(); // For one-time-use links
Dynamic Filenames or Slugs: Avoid collisions in file uploads or URLs:
$filename = "report_{$random->slug('quarterly-sales')}_{$random->date('Y-m')}.pdf";
Randomized Responses: Simulate API responses or mock data in tests:
$mockData = [
'id' => $random->uuid(),
'name' => $random->string(10),
'active' => $random->boolean(),
];
Dependency Injection:
Bind the Random class in Laravel’s service container for easy access:
// In a service provider
$this->app->singleton(Random::class, function () {
return new Random();
});
Then inject it into controllers/services:
public function __construct(private Random $random) {}
Custom Character Sets: Extend the package for domain-specific needs:
$customRandom = new Random();
$customRandom->setChars('ABCDEFGH'); // Restrict to uppercase letters
$result = $customRandom->string(5); // e.g., "GBCDA"
Seeding with Constraints:
Combine with Laravel’s Faker for realistic but random data:
$user = User::factory()->create([
'name' => $random->string(10),
'email' => "{$random->string(8)}@{$random->domain()}", // Uses Faker's domain()
]);
Performance: For bulk operations (e.g., seeding), generate all random values upfront and reuse them to avoid repeated calls:
$randomValues = collect(range(1, 100))->map(fn() => $random->string(16));
UUID Collisions:
While statistically unlikely, UUIDs generated in rapid succession (e.g., in a loop) could collide. For critical systems, validate uniqueness or use a database UNIQUE constraint.
Character Set Assumptions:
The default string() method uses alphanumeric characters (a-z, A-Z, 0-9). If you override setChars(), ensure the new set meets your requirements (e.g., avoid ambiguous characters like l, 1, O, 0).
Randomness Quality:
The package uses PHP’s random_int(), which is cryptographically secure but slower than mt_rand(). For non-security-critical use cases (e.g., test data), consider mt_rand() for performance:
$random->useMtRand(true); // Trade security for speed
Slug Edge Cases:
The slug() method replaces spaces with hyphens and trims non-alphanumeric characters. Test with edge cases like:
$random->slug('Café au Lait'); // Output: "caf-au-lait" (locale-dependent)
$random->slug('Hello--World'); // Output: "hello-world" (handles repeated separators)
Thread Safety:
The Random class is stateless and thread-safe, but if you modify its internal state (e.g., setChars()), ensure thread safety in concurrent environments.
Unexpected Output:
If string() or uuid() produces unexpected results, check for:
setChars() calls.slug() (e.g., mb_strtolower() behavior).random_int availability (requires OpenSSL).Performance Bottlenecks:
Profile with Xdebug or tideways/xhprof if generating millions of random values. Consider batching or pre-generating values.
Custom Randomizers:
Extend the Random class to add domain-specific methods:
class AppRandom extends Random {
public function password(int $length = 12): string {
$this->setChars('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*');
return $this->string($length);
}
}
Hooks for Validation: Override methods to add validation logic:
class ValidatedRandom extends Random {
public function email(): string {
$email = $this->string(8) . '@example.com';
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new \RuntimeException("Invalid email generated: {$email}");
}
return $email;
}
}
Integration with Laravel: Publish config (if the package had one) or create a config file to centralize randomness settings:
// config/random.php
return [
'default_length' => 16,
'use_mt_rand' => env('RANDOM_USE_MT_RAND', false),
];
Then bind the config to the Random instance in a service provider.
Testing Randomness:
Use PHPUnit to verify distributions (e.g., ensure boolean() returns true ~50% of the time):
public function testBooleanDistribution() {
$random = new Random();
$results = collect(range(1, 1000))->map(fn() => $random->boolean());
$trueCount = $results->filter()->count();
$this->assertGreaterThan(450, $trueCount);
$this->assertLessThan(550, $trueCount);
}
No Built-in Config:
The package is lightweight and doesn’t include a config file. All settings are method-based (e.g., setChars(), useMtRand()). For reusable settings, wrap the Random class in a facade or service.
Locale Sensitivity:
Methods like slug() rely on PHP’s multibyte functions (mb_*). Ensure your app’s locale is set correctly if working with non-ASCII characters:
setlocale(LC_ALL, 'en_US.UTF-8');
How can I help you explore Laravel packages today?