Ran into a PHP problem this morning, and [[Olle]] helped me find a workaround, so I thought I should publish here for the benefit of others.
If you are comparing two values in PHP — let’s say a password that a user has entered and a password that it stored in a database. In most cases you can compare them like this:
But — and here’s the problem — if the two values you are comparing both look to PHP like they are numbers, PHP will compare them as numbers even if they “look different.”
For example, if you are comparing 1234 with 001234, PHP will consider them to be “equal” if you compare them as above.
This is because PHP is “too smart for its own good” and “helpfully” converts all integer-like strings to integers for comparison purposes (as explained here: “If you compare two numerical strings, they are compared as integers”).
The simple solution:
By prepending a string (“s”) to each side of the comparison, PHP is prevented from helpfully converting the string to integers, and the two are thus deemed not equal as they should be.
Thanks for the help, Olle.
Comments
So you can prepend it with
So you can prepend it with anything you want, right? Doesn’t have to be “s” or “string”, but could be something less staid, like “whoooopeeeeee” or “BLAM!”, am I correct?
You could also just use the =
You could also just use the === comparison evaluator, which checks value and type, and to my opinion a bit cleaner.
if ($password_from_users === $password_in_database) {}
Or, the more language
Or, the more language agnostic way (works in most C inspired shell scripting languages):
if (!strcmp($password_from_users, $password_in_database) { login(); }
I forgot a bracket. I’m
I forgot a bracket. I’m useless without my syntax highlighting. :( Time to go apply for a job in management…
if (!strcmp($password_from_users, $password_in_database)) { login(); }
The one and only positive
The one and only positive thing I have to say about my top-of-my-head suggestion to Peter is that the === operator was introduced in PHP4. (Where would that code be when trying to run on those near-ubiquitous PHP3 servers, huh?)
But strcmp really is a mainstay since the v3 days.
In the user-contributed notes on that page, my pessimistic approach to PHP’s type system is given some happier information to use. Among the commenters, Mr Radovanovic (with a Dutch email) says it most tersely: “That’s why we should use strcmp or === (checks type also), for string comparisons.”
I think you could also do it
I think you could also do it with a cast:
if ((string) $password_from_users == (string) $password_in_database) {}
This makes it very clear what you are doing.
Matt, I tried that, and it
Matt, I tried that, and it didn’t work.
Casting doesn’t work, as php
Casting doesn’t work, as php starts from the standpoint that 001234 is a number, and hence, drops the first two zero’s before switching it to a string. Not sure why this is - just one of those weird little things in php type handling.
Add new comment