haphpiness

These are things in PHP which make me genuinely_happy();

password_hash() and password_verify()

PHP 5.5 gave developers secure password hashing with the simplest possible API. Two functions. No salt management. No algorithm selection anxiety. It defaults to bcrypt with a reasonable cost, and it's future-proof.

// Hash a password — that's it
$hash = password_hash('correct horse battery staple', PASSWORD_DEFAULT);
// $2y$12$eUz3RiQ... (bcrypt, cost 12, random salt — all automatic)

// Verify — constant-time comparison, safe against timing attacks
if (password_verify($userInput, $storedHash)) {
    // Correct password
}

// Future-proof: check if rehashing is needed (algorithm/cost changed)
if (password_needs_rehash($storedHash, PASSWORD_DEFAULT)) {
    $newHash = password_hash($userInput, PASSWORD_DEFAULT);
    updateStoredHash($userId, $newHash);
}

// Argon2 support (PHP 7.2+)
$hash = password_hash($password, PASSWORD_ARGON2ID, [
    'memory_cost' => PASSWORD_ARGON2_DEFAULT_MEMORY_COST,
    'time_cost'   => PASSWORD_ARGON2_DEFAULT_TIME_COST,
    'threads'     => PASSWORD_ARGON2_DEFAULT_THREADS,
]);

// Get algorithm info
$info = password_get_info($hash);
// ['algo' => '2y', 'algoName' => 'bcrypt', 'options' => ['cost' => 12]]

The phppassword_hash function generates a random salt automatically, encodes the algorithm and cost in the hash string, and uses a timing-safe comparison. It's nearly impossible to misuse. When PASSWORD_DEFAULT changes to a stronger algorithm in a future PHP version, phppassword_needs_rehash handles the migration transparently.

Significance: Security by Default

Before password_hash(), developers used md5(), sha1(), or rolled their own salting. The result was millions of insecure password stores. By making the secure approach the easiest approach — literally two functions — PHP eliminated an entire class of security vulnerabilities across its ecosystem.