How can PHP developers prevent SQL injection and brute-force attacks when implementing user authentication systems?

To prevent SQL injection, PHP developers should use prepared statements with parameterized queries when interacting with the database. To prevent brute-force attacks, developers should implement rate limiting by limiting the number of login attempts within a certain time frame.

// Preventing SQL injection with prepared statements
$stmt = $pdo->prepare('SELECT * FROM users WHERE username = :username AND password = :password');
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$stmt->execute();

// Preventing brute-force attacks with rate limiting
$attempts = $_SESSION['login_attempts'] ?? 0;
$maxAttempts = 5;
$timeout = 60; // 1 minute

if ($attempts >= $maxAttempts) {
    if ($_SESSION['last_login_attempt'] > time() - $timeout) {
        die('Too many login attempts. Please try again later.');
    } else {
        $_SESSION['login_attempts'] = 0;
    }
}

// Your login authentication logic here

$_SESSION['login_attempts'] = $attempts + 1;
$_SESSION['last_login_attempt'] = time();