paragonie/random_compat
PHP 5 polyfill for random_bytes() and random_int(), providing secure, cryptographically strong randomness on older PHP versions. Uses the best available system sources and falls back safely, helping apps generate tokens, keys, IDs, and nonces consistently across environments.
Install via Composer
composer require paragonie/random_compat
Since random_compat is a polyfill, it’s safe to require unconditionally—even on PHP 7+ (it no-ops there).
Start using the native API immediately
Replace any usage of mt_rand(), rand(), or uniqid() for security-critical values:
// ❌ Insecure (non-cryptographic)
$token = bin2hex(rand(1, getrandmax()));
// ✅ Secure (works on PHP 5.0+ via polyfill)
$token = bin2hex(random_bytes(16));
First use case: Generate a secure CSRF token
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
Works identically on PHP 5.6 and PHP 8.x—no code changes needed.
Abstraction layer for legacy codebases
Inject random_bytes()/random_int() via helpers or service classes to migrate gradually:
// utils.php
function secure_random_string(int $length = 16): string {
return bin2hex(random_bytes($length));
}
function secure_random_int(int $min, int $max): int {
return random_int($min, $max);
}
Security-sensitive defaults
Use random_int() for any scenario where predictability matters:
random_int(100000, 999999) for obfuscated IDs)Composer autoloading integration
No extra config needed—the package’s autoload.php is included automatically by Composer. No manual require calls required.
Laravel-specific usage
Even in modern Laravel apps, this package ensures compatibility during migrations from older PHP versions:
// In a service provider or config (if targeting PHP 5.x)
config(['app.key' => bin2hex(random_bytes(32))]); // instead of `Str::random(32)`
Fatal error on outdated PHP 5 versions
If using PHP < 5.3.7, random_compat v9+ may fail due to extension_loaded('openssl') detection. Pin to ^2.0 for legacy PHP 5.2+ support.
Fallback to less secure sources
On environments without /dev/urandom, openssl_random_pseudo_bytes(), or mcrypt_create_iv() (and no ext-libsodium), it falls back to openssl or userland CSPRNG (like openssl fallback → openssl fallback). Check the source for fallback chain—ensure openssl is enabled where fallback is critical.
Never use random_int() for non-integer requirements
It only returns integers. Use random_bytes() + encoding (e.g., bin2hex(), base64_encode()) for strings.
Avoid overuse in hot paths
While CSPRNG is fast, random_int() is not free—cache values where possible (e.g., session IDs generated at login, not on every request).
Test your polyfill
On CI, verify random_int() works:
$this->assertIsInt(random_int(1, 10));
$this->assertEquals(32, strlen(random_bytes(16)));
Deprecation warning in PHP 7.2+
If you see E_USER_DEPRECATED: A non well formed numeric value encountered, it’s likely due to custom error handlers misusing random_int()’s return. Verify type coercion in error handlers.
How can I help you explore Laravel packages today?