对于一些罕见的编码,比如GBk http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string - yes.
但您不应该因为这个原因而将其恢复。无论如何,魔术引号应该被关闭(并且将在下一个 PHP 版本中)。因此,mysql_real_escape_string() 是唯一剩下的转义函数。注意,它不是sql注入预防功能。很多人不理解这一点:它只是语法的一部分。它不能用来“保护”任何东西,而是用来组装语法正确的 SQL 查询。每次构建查询时都必须使用,无论数据来自何处。当然,作为副作用,它也会保护您免受 SQL 注入的侵害。
当然,mysql_real_escape_string()
仅适用于带引号的字符串。所以,如果你这样做
$num=mysql_real_escape_string($num);
$sql="SELECT INTO table SET data=$num"; /BAD!!!
它不会保护任何东西。
如果要使用不带引号的数字,则必须将其强制转换为正确的类型,如下所示:
$num=intval($num);
$sql="SELECT INTO table SET data=$num"; /GOOD
- 请记住,莫让
mysql_real_escape_string()
按预期工作,应设置正确的客户端编码,并且这是可能的only with mysql_set_charset()
函数,SET NAMES 查询不会设置该值。
如果你想摆脱所有这些复杂性,你可以使用准备好的陈述 http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html,尽管您需要将 mysql 驱动程序切换为 mysqli 或 PDO。
请注意,任何正确的语法或准备好的语句都无法帮助您处理除文字之外的查询部分。您无法转义标识符或运算符。如果您碰巧动态使用这些部分,则必须在脚本中对它们进行硬编码,如下所示(对于 ORDER BY 子句):
$orders=array("name","price","qty");
$key=array_search($_GET['sort'],$orders));
$orderby=$orders[$key];
$query="SELECT * FROM `table` ORDER BY $orderby";
或这个(WHERE 子句)
$w=array();
if (!empty($_GET['rooms'])) $w[]="rooms='".mysql_real_escape_string($_GET['rooms'])."'";
if (!empty($_GET['space'])) $w[]="space='".mysql_real_escape_string($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mysql_real_escape_string($_GET['max_price'])."'";
if (count($w)) $where="WHERE ".implode(' AND ',$w); else $where='';
$query="select * from table $where";