Zac*_*ack 0 mysql sql-injection
为了防止SQL注入,是否有必要使用mysql_real_escape_string(),何时magic_quotes_gpc开启?
对于一些罕见的编码,例如GBk - 是的.
但你不应该因为这个原因而回复它.无论如何应该关闭魔术引号(并且将在下一个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!!!
Run Code Online (Sandbox Code Playgroud)
它什么都不会保护.如果您要使用未引用的数字,则必须将其强制转换为强制类型,如下所示:
$num=intval($num);
$sql="SELECT INTO table SET data=$num"; /GOOD
Run Code Online (Sandbox Code Playgroud)
mysql_real_escape_string()按预期工作,应该设置正确的客户端编码,并且只能使用mysql_set_charset()函数,SET NAMES查询不会设置它.如果你想摆脱所有这些复杂性,你可以使用预准备语句,虽然你需要将你的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";
Run Code Online (Sandbox Code Playgroud)
或者这个(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";
Run Code Online (Sandbox Code Playgroud)