PHP Including Special Characters and NULL Values in Queries

Alt ernat ively, use prepare plus execute : my sth = dbh-prepare INSERT INTO profile name,birth,color,foods,cats VALUES?,?,?,?,?; my count = sth-execute DeMont, 1973-01-12, undef, eggroll, 4; I n eit her case, t he result ing query generat ed by DBI is as follows: INSERT INTO profile name,birth,color,foods,cats VALUESDe\Mont,1973-01-12,NULL,eggroll,4 Not e how DBI adds quot es around dat a values, even t hough t here were none around t he ? placeholder charact ers in t he original query st ring. The placeholder m echanism adds quot es around num eric values, t oo, but t hat s okay, because t he MySQL server perform s t ype conversion as necessary t o convert st rings t o num bers. Also not e t he DBI convent ion t hat when you bind undef t o a placeholder, DBI put s a NULL int o t he query and correct ly refrains from adding surrounding quot es. DBI also provides a quote m et hod as an alt ernat ive t o using placeholders. quote is a dat abase handle m et hod, so you m ust have a connect ion open t o t he server before you can use it . This is because t he proper quot ing rules cannot be select ed unt il t he driver is known; som e dat abases have different quot ing rules t han ot hers. Heres how t o use quote t o creat e a query st ring for insert ing a new record in t he profile t able: my stmt = sprintf INSERT INTO profile name,birth,color,foods,cats VALUESs,s,s,s,s, dbh-quote DeMont, dbh-quote 1973-01-12, dbh-quote undef, dbh-quote eggroll, dbh-quote 4; my count = dbh-do stmt; The query st ring generat ed by t his code is t he sam e as when you use placeholders. The s form at specifiers are writ t en wit hout surrounding quot es because quote provides t hem aut om at ically as necessary: undef values are insert ed as NULL wit hout quot es, and non- undef values are insert ed wit h quot es.

2.8.5 PHP

PHP has no placeholder capabilit y, but does provide an addslashes funct ion t hat you can use t o m ake values safe for insert ion int o query st rings. addslashes escapes special charact ers such as quot es and backslashes, but does not add surrounding quot es around values; you m ust add t hem yourself. We also need a convent ion for specifying NULL values; let s t ry using unset t o force a variable t o have no value som ewhat like Perls undef value . Here is som e PHP code for adding DeMont s profile t able record: unset null; create a null value stmt = sprintf INSERT INTO profile name,birth,color,foods,cats VALUESs,s,s,s,s, addslashes DeMont, addslashes 1973-01-12, addslashes null, addslashes eggroll, addslashes 4; result_id = mysql_query stmt, conn_id; I n t he exam ple, t he s form at specifiers in t he query st ring are surrounded wit h quot es because addslashes doesnt provide t hem . Unfort unat ely, t he result ing query st ring looks like t his, which isnt quit e correct : INSERT INTO profile name,birth,color,foods,cats VALUESDe\Mont,1973-01-12,,eggroll,4 The quot e in t he name field has been escaped properly, but t he null unset value we passed for t he color colum n t urned int o an em pt y st ring, not NULL . Let s fix t his by w rit ing a helper funct ion sql_quote t o use in place of addslashes . sql_quote is sim ilar t o addslashes , but ret urns NULL wit hout surrounding quot es for unset values and adds quot es around t he value ot herwise. Heres what it looks like: function sql_quote str { return isset str ? . addslashes str . : NULL; } Because sql_quote it self adds quot e charact ers around t he dat a value if t heyre needed, we can rem ove t he quot es t hat surround t he s form at specifiers in t he query st ring and generat e t he INSERT st at em ent like t his: unset null; create a null value stmt = sprintf INSERT INTO profile name,birth,color,foods,cats VALUESs,s,s,s,s, sql_quote DeMont, sql_quote 1973-01-12, sql_quote null, sql_quote eggroll, sql_quote 4; result_id = mysql_query stmt, conn_id; Aft er m aking t he preceding changes, t he value of stmt includes a properly unquot ed NULL value: INSERT INTO profile name,birth,color,foods,cats VALUESDe\Mont,1973-01-12,NULL,eggroll,4 I f youre using PHP 4, you have som e addit ional opt ions for handling NULL values and special charact ers. First , PHP 4 has a special value NULL t hat is like an unset value, so you could use t hat in place of null in t he preceding code t hat generat ed t he INSERT st at em ent . However, t o writ e code t hat works for bot h PHP 3 and PHP 4, use an unset variable such as null . Second, as of PHP 4.0.3, an alt ernat ive t o addslashes is t o use mysql_escape_string , which is based on t he funct ion of t he sam e nam e in t he MySQL C API . For exam ple, you could rewrit e sql_quote t o use mysql_escape_string like t his: function sql_quote str { return isset str ? . mysql_escape_string str . : NULL; } I f you want a version t hat uses mysql_escape_string if it s present and falls back t o addslashes ot herwise, writ e sql_quote like t his: function sql_quote str { if isset str return NULL; func = function_exists mysql_escape_string ? mysql_escape_string : addslashes; return . func str . ; } Whichever version of sql_quote you use, it s t he kind of rout ine t hat is a good candidat e for inclusion in a library file. I ll assum e it s availabilit y for PHP script s in t he rest of t his book. You can find it as part of t he Cookbook_Ut ils.php file in t he lib direct ory of t he recipes dist ribut ion. To use t he file, inst all it in t he sam e locat ion where you put Cookbook.php and reference it from script s like t his: include Cookbook_Utils.php;

2.8.6 Python