Генерируем безопасный пароль под требования

Генерирует пароль, удовлетворяющий требованиям
/**
 * Генерирует пароль, удовлетворяющий следующим требованиям:
 * - Минимальная длина 10 символов.
 * - Обязательное наличие хотя бы одной заглавной буквы.
 * - Обязательное наличие хотя бы одной строчной буквы.
 * - Обязательное наличие хотя бы одной цифры.
 * - Обязательное наличие хотя бы одного спецсимвола.
 *
 * @param int $length Желаемая длина пароля (не менее 10 символов).
 * @return string Сгенерированный пароль.
 * @throws Exception Если заданная длина меньше 10.
 */
function generatePassword($length = 10) {
    if ($length < 10) {
        throw new Exception("Длина пароля должна быть не менее 10 символов.");
    }

    $upper   = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $lower   = 'abcdefghijklmnopqrstuvwxyz';
    $digits  = '0123456789';
    $special = '!@#$%^&*()_+-=[]{}|;:,.<>?';

    // Обеспечим наличие по одному символу из каждой категории
    $password = [];
    $password[] = $upper[random_int(0, strlen($upper) - 1)];
    $password[] = $lower[random_int(0, strlen($lower) - 1)];
    $password[] = $digits[random_int(0, strlen($digits) - 1)];
    $password[] = $special[random_int(0, strlen($special) - 1)];

    // Объединённый набор символов для заполнения оставшейся части пароля
    $all = $upper . $lower . $digits . $special;
    for ($i = 4; $i < $length; $i++) {
        $password[] = $all[random_int(0, strlen($all) - 1)];
    }

    // Перемешиваем массив, чтобы гарантированные символы распределились случайным образом
    shuffle($password);

    return implode('', $password);
}

// Пример использования:
try {
    $password = generatePassword(12); // Можно задать любую длину не менее 10 символов
    echo "Сгенерированный пароль: " . $password;
} catch (Exception $e) {
    echo "Ошибка: " . $e->getMessage();
}