The password_verify is working as expected but when in the if statement it is always evaluated as false.
It's actually the other way around - your if
statement is fine, but password_verify
is returning false
, and the way you tried to debug that was wrong, misleading you.
To see why, try running this code:
function something_that_returns_false() {
return false;
}
echo 'Some text that disappears? ' . something_that_returns_false() ? "It was true": "It was false";
You might expect this to print Some text that disappears? It was false
, but instead it just prints It was true
!
Why? Because PHP doesn't read this the way you think it would; it looks first at this bit:
'Some text that disappears? ' . something_that_returns_false()
First it runs something_that_returns_false()
, gets false
, and decides how to represent that as a string, which in PHP is an empty string. That gets concatenated to the string 'Some text that disappears? '
(so, we just have that original string).
Then it checks whether that string should be considered "true". In PHP, any non-empty string is considered "true" in such contexts, so it ends up running this:
echo true ? "It was true": "It was false";
Which of course will print It was true
.
To avoid this, use parentheses around the part you want to be evaluated separately - it's a good habit to always do this when using the ternary operator (a ? b : c
):
function something_that_returns_false() {
return false;
}
echo 'Some text that disappears? ' . (something_that_returns_false() ? "It was true": "It was false");
Now it prints Some text that disappears? It was false
, which is more useful.
More simply, to test the value of something, you can use var_dump, which shows the exact value of the expression.
In your case:
var_dump( password_verify($_POST['password'], $password) );
You will find that this prints bool(false)
, because somewhere you've got the use of password_verify
wrong. See How to use PHP's password_hash to hash and verify passwords for some things to look at next.