Pathologically Eclectic Rubbish Lister | |
PerlMonks |
comment on |
( [id://3333]=superdoc: print w/replies, xml ) | Need Help?? |
Escaping is not done to put lovely backslashes in the database. Escaping is just to make sure the data gets in the database correctly. SQL uses quotes to delimit text, so they need to be escaped when the data contains them, and you of course need to escape the character you use to escape other things with.
With INSERT INTO foo VALUES ('bar\'baz') the string bar'baz is stored, without the backslash. It's like saying print "bar\"baz", which prints only bar"baz, again without the backslash itself. Many, many PHP programmers are confused about escaping and quoting, because PHP quotes strings for you by default. That is, if you have the user input bar'baz, the actual string content will be bar\'baz, which is terribly wrong and confusing. (Blame PHP.) Some then read mysql can't handle single quotes, because they're used as delimiter and start escaping the quotes and backslashes, turning the string into bar\\\'baz, and with 'bar\\\'baz' in an SQL query, bar\'baz is stored in the database. This is where a lot of web programmers using PHP go wrong. They have escaped data in their database, which is very confusing, and a waste of space. DBI has a nice escaping mechanism. Instead of escaping everything that could be dangerous, only that what is dangerous is escaped. If you have the user input bar'baz in Perl, your string will have those 7 characters, and no disgusting automatic escaping. That means you will have to arrange for the backslash to be there yourself. You could do it the hard and potentially dangerous way, by using quotemeta or some s///-construct, but DBI has a database-specific method called quote, which is handled internally if you use placeholders. If you use that, the data is turned into bar\'baz for usage in an SQL query. In the query, there will be 'bar\'baz', so the data stored in the database is bar'baz. That also means you do not have to un-escape what you get out of the database. (Again PHP confuses people by having a function that un-escapes automatically. If with SQL everthing is done the way it's supposed to be done, you never have to unescape, because there are no escapes in the database!) The following script will create a test2 table in the test database, and insert and immediately select the data that follows __DATA__ (through the magic DATA filehandle). It will then report whether the data has changed or not:
(I experimented a little with style in here. When you read everything that is indented by one level, you read only the program flow. I haven't used this style before, but I kind of like it. Please let me know what you think about having the methods indented like this.) HTH
In reply to Re: Backslashes with DBI quote( ) and MySQL
by Juerd
|
|