Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

treat an empty new-password field as “no password change.” Update the profile without touching the password column. If a new password is supplied, require confirmation, hash it with password_hash(), and save only the hash. Never hash an empty string and write that result over the existing password.

Use the submitted password to choose the update path

Read both password fields from POST. A blank new-password value means the user is editing profile data only. A non-blank value starts a password-change request.

  • Blank new password: omit password from the SQL UPDATE, so the stored hash remains unchanged.
  • Non-blank new password: compare it with the confirmation field, reject a mismatch, create a replacement with password_hash($newPassword, PASSWORD_DEFAULT), and update the hash.

Example with two complete prepared statements

Adapt the column names, authorization checks, and validation rules to your application. Every value from the request or the edited record is passed through a PDO parameter.

<?php
$newPassword = (string)($_POST['password'] ?? '');
$confirm     = (string)($_POST['confirm_pwd'] ?? '');

if ($newPassword === '') {
    $stmt = $pdo->prepare(
        'UPDATE users
         SET role_id = :role_id,
             first_name = :first_name,
             last_name = :last_name,
             email = :email,
             username = :username,
             status = :status
         WHERE id = :id'
    );

    $params = [
        ':role_id'    => $roleId,
        ':first_name' => $firstName,
        ':last_name'  => $lastName,
        ':email'      => $email,
        ':username'   => $username,
        ':status'     => $status,
        ':id'         => $id,
    ];
} else {
    if (!hash_equals($newPassword, $confirm)) {
        throw new RuntimeException('Password confirmation does not match.');
    }

    $stmt = $pdo->prepare(
        'UPDATE users
         SET role_id = :role_id,
             first_name = :first_name,
             last_name = :last_name,
             email = :email,
             username = :username,
             password = :password,
             status = :status
         WHERE id = :id'
    );

    $params = [
        ':role_id'    => $roleId,
        ':first_name' => $firstName,
        ':last_name'  => $lastName,
        ':email'      => $email,
        ':username'   => $username,
        ':password'   => password_hash($newPassword, PASSWORD_DEFAULT),
        ':status'     => $status,
        ':id'         => $id,
    ];
}

$stmt->execute($params);

Why the blank branch must omit the password column

An SQL assignment such as password = :password changes the stored value every time the statement runs. Binding an empty form value, or binding password_hash('' , PASSWORD_DEFAULT), therefore replaces a valid hash with a value the user did not intend to set. Leaving the column out of the statement lets the database retain the existing hash.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Validate the password-change branch before writing

Require a non-empty replacement

The branch itself establishes that a change was requested. Apply any additional policy your application requires, such as minimum length, breached-password checks, or disallowed values.

Check confirmation

Compare the new and confirmation values before executing the update. The example uses hash_equals(); a normal exact comparison is also appropriate for two values supplied by the same form, provided both are compared without trimming or altering the intended password.

Hash only the replacement

password_hash() creates a salted, algorithm-tagged hash. Store its return value, not the plaintext password. Do not generate a hash when the field is blank.

Use parameters for every user-supplied value

Prepare the SQL and pass values through matching named markers in execute() (or bind them with bindValue()). Do not concatenate request values into SQL. Besides protecting the query from injection, matching markers make it clear which values are being written.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Alternative: separate profile and password updates

You can always run a profile-only update, then run a second statement only when a password change was requested.

  1. Validate the record identifier, profile fields, and authorization.
  2. Execute an UPDATE that contains no password assignment.
  3. If the new-password field is non-empty, verify the confirmation and execute a password-only UPDATE users SET password = :password WHERE id = :id.

This layout isolates the security-sensitive operation and is easy to audit. If both writes must succeed or fail together, wrap them in a PDO transaction and roll back when either statement or validation fails. A single conditional statement is simpler when the existing form and API already expect one write.

Design Password can be overwritten accidentally Validation flow Auditability Failure handling
Two alternate complete updates Low, because the blank SQL has no password column Clearly branches before execution One place shows each complete record shape One statement; straightforward error handling
Profile update plus password-only update Low, because the password statement runs only on request Password logic is isolated Easy to review as a dedicated password path Use a transaction when both writes must be atomic
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Verify the stored hash at login

When authenticating, fetch the stored hash for the account and call password_verify() with the submitted plaintext password and that hash:

if (password_verify($submittedPassword, $storedHash)) {
    // Authenticate the user.
}

The hash contains the algorithm, cost, and salt information needed for verification. The function performs the comparison in a timing-attack-resistant manner. Never compare a submitted plaintext password directly with the database value.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Common failure modes

  • Hashing the empty field: test for '' before calling password_hash().
  • Including password in every update: remove that assignment from the profile-only SQL.
  • Updating before confirmation: compare the two new-password fields first and abort on mismatch.
  • Using plaintext or reversible encryption: store only the result of password_hash().
  • Interpolating request data into SQL: use prepared statements and parameter markers for every value.
  • Ignoring partial failures: use a transaction when separate profile and password writes must be atomic.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.