Generating random strings in PHP is a common requirement for many applications — from creating secure passwords and API tokens to generating temporary file names and verification codes. In this tutorial, you'll see three robust ways to generate PHP random strings, compare their strengths and weaknesses, and pick the best option for your use case.
Why Generate Random Strings in PHP?
Random strings are used for a variety of reasons in modern web applications:
- Session tokens for authentication
- Password reset codes or email verification links
- API keys or secret tokens
- Random filenames for uploads
- Captcha and security validation
The quality of the randomness, desired length, and allowed characters all matter when choosing your approach. Below are three production-friendly methods.
rand()
, mt_rand()
, or str_shuffle()
for tokens. Use
random_bytes()
/ random_int()
for cryptographic strength.
Method 1: bin2hex(random_bytes())
— Cryptographically Secure
function generateRandomStringSecure($length = 32) {
// Each byte becomes 2 hex chars; ceil handles odd lengths
$bytes = random_bytes((int) ceil($length / 2));
return substr(bin2hex($bytes), 0, $length);
}
How It Works
random_bytes()
generates cryptographically secure bytes.bin2hex()
converts bytes to hex (characters0–9
,a–f
).
Pros
- Cryptographically secure
- Fast and built-in (PHP 7+)
Cons
- Hex output only (no letters A–Z beyond
a–f
)
Best for: API tokens, session keys, and security-sensitive identifiers.
Method 2: random_int()
with a Custom Character Set
function generateRandomStringSimple($length = 16, $alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
$alphabetLength = strlen($alphabet);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $alphabet[random_int(0, $alphabetLength - 1)];
}
return $randomString;
}
How It Works
- Define a character pool (e.g., digits + upper/lowercase letters).
- Use
random_int()
(CSPRNG) to pick random indices from the pool.
Pros
- Highly customizable (add symbols, remove ambiguous chars, etc.)
- Readable strings for URLs, usernames, invites
Cons
- Looping with
random_int()
can be slightly slower for very long strings
Best for: Human-readable codes, usernames, short URLs.
Method 3: openssl_random_pseudo_bytes()
function generateRandomStringOpenSSL($length = 32) {
// Fallback for legacy PHP (< 7)
$bytes = openssl_random_pseudo_bytes((int) ceil($length / 2), $cryptoStrong);
if ($bytes === false || $cryptoStrong === false) {
throw new RuntimeException('OpenSSL RNG not strong on this system');
}
return substr(bin2hex($bytes), 0, $length);
}
How It Works
- Generates random bytes via OpenSSL; strength can vary by system.
Pros
- Backwards compatible (PHP 5.3+)
Cons
- Prefer
random_bytes()
when available (PHP 7+) - Must check the
$cryptoStrong
flag
Best for: Legacy projects where random_bytes()
isn’t available.
Comparing All Three Methods
Method | Security | Custom Characters | PHP Version | Performance |
---|---|---|---|---|
random_bytes() + bin2hex() |
✔️ Very secure | ❌ Hex only | 7.0+ | ⚡ Fast |
Character pool + random_int() |
✔️ Secure | ✔️ Yes | 7.0+ | ⚡ Medium |
openssl_random_pseudo_bytes() |
✔️ Usually secure | ❌ Hex only | 5.3+ | ⚡ Fast |
Tips for Production Usage
- Prefer
random_bytes()
/random_int()
in modern PHP. - If you need a specific length, handle odd lengths (use
ceil()
or trim the hex output). - Add prefixes like
usr_
,api_
,img_
to categorize IDs. - Store sensitive data securely (prepared statements, hashing where appropriate).
Bonus: Random Strings with Symbols and Numbers
function generateComplexRandomString($length = 16, $alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()-_=+') {
$alphabetLength = strlen($alphabet);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $alphabet[random_int(0, $alphabetLength - 1)];
}
return $randomString;
}
This variation includes special characters, making it suitable for passwords and authentication tokens. For URL-safe tokens,
consider a Base64URL approach (replace +
//
with -
/_
and trim =
padding).