A modern, flexible, and secure password generator built for PHP 8.2+. Designed with configuration-first principles, it supports character-type rules, avoidance of consecutive characters, and rich presets out of the box.
- PHP 8.2+ with
readonlyand strong types - Configurable character pools: lowercase, uppercase, numbers, symbols
- Range-based character counts via
PoolRange - Always start with a letter (optional)
- Avoid consecutive characters (enabled by default)
- Character exclusion (e.g., omit
l,1,0,O) - Built-in presets (safe, strong, human-friendly, dev)
- Pest-based test suite
- Clean Composer autoloading (PSR-4)
composer require kristos80/password-generator<?php
declare(strict_types=1);
require_once __DIR__ . "/vendor/autoload.php";
use Kristos80\PasswordGenerator\PasswordGenerator;
use Kristos80\PasswordGenerator\PasswordGeneratorConfigFactory;
$config = PasswordGeneratorConfigFactory::safeDefault();
$password = (new PasswordGenerator())->generate($config);
echo $password; //Cf<q{h8q4M%Balanced password with 3 lowercase, 2 uppercase, 2 numbers, 2 symbols.
Avoids confusing characters like l, 1, 0, O.
16-20 character high-entropy password with balanced character pools.
No symbols, avoids ambiguous characters. Easier to type & read.
Perfect for password vaults or power users. Focuses on symbol density.
Ideal for API tokens: all alphanumeric, no symbols, fixed length.
You can define your own ranges:
use Kristos80\PasswordGenerator\PasswordGeneratorConfig;
use Kristos80\PasswordGenerator\PoolRange;
$config = new PasswordGeneratorConfig(
new PoolRange(3, 5), // lowercase
new PoolRange(2, 4), // uppercase
new PoolRange(2, 2), // numbers
new PoolRange(1, 2), // symbols
true, // must start with a letter
['l', '1', '0', 'O'] // characters to exclude
);Then:
$password = (new PasswordGenerator())->generate($config);Consecutive identical characters are avoided (e.g., aa, 11, $$), with up to 5 reshuffling attempts internally.
When enabled, the password will always begin with a letter (a-z or A-Z).
Characters passed via doNotUse will never appear in the final password, case-insensitively.
This package uses Pest for testing.
composer testMIT © Kristos80