What does mysql_real_escape_string() do that addslashes() doesn't?

Addslashes is generally not good enough when dealing with multibyte encoded strings.


It adds slashes to:

\x00, \n, \r, \, ', " and \x1a. characters.

Where addslashes only adds slashes to

' \ and NUL

Ilias article is also pretty detailed on its functionality


gs's harshly downvoted answer is actually kinda right.

Standard SQL uses doubling to escape a literal apostrophe. MySQL's non-standard use of backslashes for escaping is the default setting, but it can be disabled and often is, in particular in sql_mode ANSI.

In this case only the doubled syntax will work, and any app you have using addslashes (or other ad-hoc escaping method) will break. mysql_real_escape_string will use whichever escaping method is best for the connection's sql_mode.

The multibyte encoding issue is also important if you're still using those nasty East Asian encodings that re-use the lower 128 characters, but then really you want to be using UTF-8 instead. \n-escaping, on the other hand, is of no concern since MySQL can perfectly happily cope with a raw newline in a statement.


mysql_real_escape_string does a lot more than addslashes does.

addslashes operates on pure ascii, without knowing anything about the database. It escapes:

  • '\'
  • "\"
  • \\\
  • ASCII 0\0.

mysql_real_escape_string's purpose is to "create a legal SQL string that you can use in an SQL statement." mysql_real_escape_string takes into account the current character set of the connection (which is why you must always pass a valid $mysql object).

It does the following (taken from the MySQL C API documentation):

  • Encodes: \, ', ", ASCII 0, \n, \r, and Control+Z in a way that won't cause problems
  • ensures a 0 byte terminates the string (in the C api)
  • may perform a multibyte (ascii) to wide character conversion if the DB linked to in $mysql uses a wide character set.

I don't really know how PHP stores strings internally, but the point is all of this is available to PHP when you use mysql_real_escape_string. I guess the main point of difference is mysql_real_escape_string considers the character set of the connection, where addslashes cannot (it doesn't even know what DB you are connected to).