In PHP: 1234 == 001234

Peter Rukavina

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:

if ($password_from_users == $password_in_database) {}

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:

if (“s” . $password_from_users == “s” . $password_in_database) {}

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

Submitted by Rob L. on

Permalink

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?

Submitted by Charles on

Permalink

Or, the more language agnostic way (works in most C inspired shell scripting languages):
if (!strcmp($password_from_users, $password_in_database) { login(); }

Submitted by Charles on

Permalink

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(); }

Submitted by Olle Jonsson on

Permalink

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.”

Submitted by Matt on

Permalink

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.

Submitted by Isaac Grant on

Permalink

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

Plain text

  • Allowed HTML tags: <b> <i> <em> <strong> <blockquote> <code> <ul> <ol> <li>
  • Lines and paragraphs break automatically.

About This Blog

Photo of Peter RukavinaI am . I am a writer, letterpress printer, and a curious person.

To learn more about me, read my /nowlook at my bio, listen to audio I’ve posted, read presentations and speeches I’ve written, or get in touch (peter@rukavina.net is the quickest way). 

You can subscribe to an RSS feed of posts, an RSS feed of comments, or a podcast RSS feed that just contains audio posts. You can also receive a daily digests of posts by email.

Search