Str::password
Generates a random password of a given length containing letters, numbers and symbols.
Str::password(int $length = 32, bool $letters = true, bool $numbers = true, bool $symbols = true, bool $spaces = false): stringParameters
| Parameter | Type | Description |
|---|---|---|
$$lengthoptional | int= 32 | Desired length. If it is smaller than the number of enabled character classes, the result is one character per class instead. |
$$lettersoptional | bool= true | Include a-z and A-Z. |
$$numbersoptional | bool= true | Include 0-9. |
$$symbolsoptional | bool= true | Include the symbol set ~ ! # $ % ^ & * ( ) - _ . , < > ? / \ { } [ ] | : ; |
$$spacesoptional | bool= false | Include the space character as a fourth class. |
Return value
stringA shuffled password containing at least one character from every enabled character class.
Errors
Throws a ValueError when every character class is disabled, and random_int may throw Random\RandomException if the platform has no secure randomness source.
Str::password builds a password from up to four character classes, guaranteeing at least one character from each enabled class before filling the remaining length at random and shuffling the whole thing. Every draw uses random_int, so it is suitable for credentials — unlike rand or shuffle on a character array.
When to use it
Temporary passwords for invited users, seeded credentials in a factory, or a generated secret you immediately hash and hand to the person once. It is not for API tokens: those want the URL-safe alphanumeric output of Str::random, because the symbol set here includes backslash, braces and pipe, all of which need escaping somewhere.
The short-length trap
The guaranteed characters are pushed first and the remaining length is calculated by subtracting them. With the defaults that means three classes, so Str::password(2) returns a three-character string — longer than you asked for. Anything at or below the number of enabled classes silently ignores your length.
Disabling everything throws
Turning off letters, numbers, symbols and spaces leaves no pool to draw from and the internal random_int(0, -1) raises a ValueError. Guard against config that could disable every class.
Example
When to use it
- Issue a temporary password when an administrator invites a user by email.
- Seed a demo or factory account with a credential nobody can guess.
- Generate a one-off secret to hash and display once during onboarding.
Frequently asked questions
Is Str::password cryptographically secure?
Yes. Every character is selected with random_int, which draws from the operating system's cryptographically secure random source, and the final string is shuffled the same way. It is safe for credentials, unlike rand() or str_shuffle().
Why did Str::password return more characters than I asked for?
One character from each enabled class is added before the requested length is honoured, so with the default three classes any length below 3 still yields a 3-character password. Ask for a realistic length, or disable classes you do not need.
How do I generate a password without symbols?
Pass symbols: false, as in Str::password(16, symbols: false), which leaves letters and numbers. Do this whenever the value has to survive a shell command, a URL, or a system with a restrictive complexity policy.
More examples
Inviting a user with a temporary password
The generated password is hashed before it touches the database and the plaintext is passed straight to the notification, never stored or logged. must_change_password forces a rotation on first sign-in. Requires a booted application for Hash and Eloquent.
<?php
namespace App\Actions;
use App\Models\User;
use App\Notifications\AccountInvited;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class InviteUser
{
public function handle(string $email): User
{
$password = Str::password(16);
$user = User::create([
'email' => Str::lower($email),
'password' => Hash::make($password),
'must_change_password' => true,
]);
// The plaintext exists only inside this method and the notification.
$user->notify(new AccountInvited($password));
return $user;
}
}Choosing a character set the downstream system accepts
Because at least one character from every enabled class is guaranteed, the assertions hold on every run — the default set always contains a symbol and the PIN never contains a letter. That guarantee is what makes the flags useful for satisfying a downstream complexity rule.
<?php
use Illuminate\Support\Str;
// Default: letters, numbers and symbols, no spaces.
$default = Str::password(20);
// Alphanumeric only — safe to paste into a shell or a URL.
$safe = Str::password(20, symbols: false);
// A numeric PIN.
$pin = Str::password(8, letters: false, symbols: false);
printf("default: %d chars, symbols present: %s\n",
strlen($default),
preg_match('/[^A-Za-z0-9]/', $default) ? 'yes' : 'no');
printf("safe: %d chars, alphanumeric: %s\n",
strlen($safe),
ctype_alnum($safe) ? 'yes' : 'no');
printf("pin: %d chars, digits only: %s\n",
strlen($pin),
ctype_digit($pin) ? 'yes' : 'no');
// default: 20 chars, symbols present: yes
// safe: 20 chars, alphanumeric: yes
// pin: 8 chars, digits only: yes
Discussion