Episode One

09 Aug 2005

No, I'm not talking about Star Wars. The first episode of Ask Chris is now online. In this episode, I am asked about a comment I made during my talk at PHP West. During the talk, someone asked when stripslashes() should be used, and I said it should never be used. I was being a bit cheeky, but I thought it was funny. :-) I went a bit further, noting that if you ever find yourself removing the escaping of something, you've probably screwed up somewhere. I didn't substantiate this remark (because it was tangential to the current topic), so many people have, understandably, questioned it.

Based on the comments, I apparently haven't clarified the issue very well, so let me explain further.

When you send data to a remote system, it often enters a context where it might be interpreted to be something other than data (there are caveats, such as when you're using bound parameters). In order to preserve the data when it enters this other context, you need to escape it. This means different things in different contexts, but the basic idea is consistent.

One common example is the use of data in an SQL query. For example:

  2. $sql = "INSERT
  3.         INTO   users (last_name)
  4.         VALUES ('$last_name')";

If $last_name is O'Reilly, this query becomes:

  1. INTO users (last_name)

That's going to break, because the ' in O'Reilly affects the format of the SQL query - it's considered to be something other than data. In order to avoid this, it needs to be escaped. If you're using MySQL, you use mysql_real_escape_string() for the escaping, so O'Reilly becomes O\'Reilly. This makes the query look a bit better:

  1. INTO users (last_name)

Now, here's the tricky part. Guess what is stored in the database. Easy, right? The answer is O'Reilly (sans backslash). If you don't believe me, try it for yourself. Sure, you can stripslashes() on O'Reilly, but there are no backslashes to be stripped, so it's pointless (plus some day your data might really have some backslashes in it). Now, imagine my surprise when I read this comment:

Of course, you face the problem of what do to if you already have a large number of records already stored in a database that have NOT been escaped with mysql_real_escape_string().

In the words of enygma:

Ow. My eyes.