Wednesday 22 October 2003 — This is 21 years old. Be careful.
I just added a preview button to my comment system (try it out!), and along the way was reminded about what is good and bad about PHP. It isn’t two different things, it’s one thing: magic.
As I was working on the preview button, I was nagged by something which had bothered me before: string quoting with slashes. Looking at the data I was getting back from POSTed web forms, it already had slashes in it to quote apostrophes, double quotes, and so on. I thought I had added them myself somewhere, but could not find the place I had called addslashes. It’s natural that while passing strings from posted forms to MySQL and back to HTML, there’s a lot of slash-munging. I figured I had an old call to addslashes somewhere.
It turns out I didn’t. There is a configuration setting which automatically applies slash-quoting to the values retrieved from GET, POST, and COOKIE values. The setting is called magic_quotes_gpc. It can be set in the php.ini file, and its value can be checked with the get_magic_quotes_gpc function. There is no way to programmatically change its setting.
There’s another similar setting called magic_quotes_runtime which applies quoting automatically to external data such as databases and file contents. It can be queried with the get_magic_quotes_runtime function, and also changed programmatically with the set_magic_quotes_runtime function. Why can one be changed at runtime and the other cannot? I don’t know. Maybe there’s a good reason, maybe not.
These magic settings are just the sort of thing PHP is famous for. They do exactly the right thing for the beginner who wants to write code to run on his web server. They are special purpose functions which do a specific web job really well. If you are moving up from HTML and JavaScript, and have to write server-side code, PHP will fit you like a glove. If you approach coding empirically, then magic_quotes_gpc is no problem. You try the code, and see that slashes have been applied, and deal with it.
But if you have a more analytical approach, then magic_quotes_gpc is the kind of thing that will drive you nuts. I spent twenty minutes today rediscovering this magic quoting feature, because I couldn’t figure out why there were slashes in my POST data.
PHP is not clean. Its strength is that it is grungy, but in precisely the right ways to make simple server-side coding tasks easy. It provides tight integration between the programming language and the web server, it has a rich library for doing lots of webby stuff, and it has a simple forgiving feel to it. But once you graduate to larger coding projects, or delivering software to someone else’s server, or structuring your code for more modularity, then PHP begins to run out of steam, and its initial strengths become weaknesses.
Comments
I much prefer the way Python handles database escaping. In Python you simply say cursor.execute('insert into table values (%s, %s)', (value1, value2)) and the Python database layer figures out the quoting for you.
So then you think it's best to just turn magic_quotes off. Then you get the evil backslashes. It's the worst with preview forms and the like, because one ' turns into a \', then in the preview it turns into \\\', then \\\\\\\', etc. as it is resubmitted or re-edited.
If PHP made magic quotes manditory then it wouldn't be a big deal -- you'd learn to unquote when necessary. (Well, many people would be too lazy to do it, but at least you *could* do the right thing). But by making it an option it's the worst of both worlds. If you don't specifically check for the setting you are either unsafe or sloppy.
In previous versions you had no choice, you needed magic "on" (if I remember correctly). Now you set as you wish.
Enjoy, Michael
...and then it’s time to move to Python. ;-)
IMHO the problem is that PHP’magic_quotes fixes the ‘escaping stuff that has to go in a database’-problem in the wrong place. As Simon illustrated above, the Python DB-api takes care of any escaping when sending your query to the database, where this should be done.
Besides, magic quotes does not make any sense when you want to do something else with the posted data besides storing it in a relational database.
function escape_data ($data) {
if (get_magic_quotes_gpc()) $data=stripslashes($data);
return mysql_escape_string(trim($data));
}
This way, my data's escaped the way MySQL likes it, my SELECT queries return strings that I can work with immediately, and I can easily move my pages from server to server without adjustments.
Add a comment: