PDO has the PDO::Quote()
method which does the same job as mysql_real_escape_string()
. This provides basically the same functionality and the sme level of security.
A better option is the "Prepared Statements" functionality, where you put markers into the query rather than variables using PDO::prepare()
, and then use PDO::execute()
to pass the variables to the query.
This is more secure because it uses the database engine's internal mechanisms to push the variables into the query. There is zero possibility of a SQL injection attack via a prepared statement (unless the database engine itself has a bug, but that's something you would mitigate by keeping you MySQL version patched up to date; nothing to do with your own code).
Prepared statements also have the bonus that they can be cached by the database engine. This means that if you make multiple calls using the same query but with different variable values, then you will get a performance boost compared with making the same queries using the old string-based mechanism.
Note: Some DBs may not support prepared statements natively, in which case PHP will emulate them. In this case, it's basically the same as using PDO::Quote
, and you don't get the benefits listed above. Most DBs do support them tho, but even then it is possible for it to be disabled, so make sure you switch off ATTR_EMULATE_PREPARES
.
Finally, using PDO is more secure because the old mysql extension had some fundamental security issues at its core. For example, the old API does not encrypt the communications between PHP and the MySQL database. This means that there is a theoretical risk of an eavesdropper attack, particularly if the DB is not on the same server as PHP. PDO uses a more recent version of the MySQL comms protocol, and is thus able to encrypt this traffic and as a result is more secure (and also why PDO doesn't support really ancient versions of MySQL). There are a handful of other similar hidden risks with the old API that were so deeply ingrained in the code that they could not be removed. This is why the mysqli
extension was written as a direct replacement for it.