有没有更简单的方法来安全地提取除以下之外的提交变量?
if(isset($_REQUEST['kkld'])) $kkld=mysql_real_escape_string($_REQUEST['kkld']);
if(isset($_REQUEST['info'])) $info=mysql_real_escape_string($_REQUEST['info']);
if(isset($_REQUEST['freq'])) $freq=mysql_real_escape_string($_REQUEST['freq']);
(并且:你会在这种情况下使用isset()
吗?)
要一次性逃避所有变量:
$escapedGet = array_map('mysql_real_escape_string', $_GET);
要将所有变量提取到当前命名空间(即$foo = $_GET['foo']
):
extract($escapedGet);
不过请不要这样做。没有必要,只需将值保留在数组中即可。提取变量可能导致名称冲突和覆盖现有变量,这不仅是一个麻烦和错误的来源,而且还有安全风险。另外,正如@BoltClock所说,坚持使用$_GET
或$_POST
。另外,正如@zerkms所指出的那样,在数据库查询中不应该使用的mysql_real_escaping
变量没有任何意义,它甚至可能导致进一步的问题。
请注意,这根本不是一个特别好的想法,你只是转发magic_quotes和global_vars,这是过去几年中可怕的PHP实践。通过mysqli或PDO使用带有绑定参数的预准备语句,并通过$_GET
或filter_input
使用值。见http://www.phptherightway.com。
您也可以使用这样的递归函数来实现这一目标
function sanitate($array) {
foreach($array as $key=>$value) {
if(is_array($value)) { sanitate($value); }
else { $array[$key] = mysql_real_escape_string($value); }
}
return $array;
}
sanitate($_POST);
据我所知,Starx'和Ryan在2010年11月19日的答案是最好的解决方案,因为我也需要这个。
如果有多个带有一个名称的输入字段(例如names []),意味着它们将保存到$ _POST数组中的数组中,则必须使用递归函数,因为mysql_real_escape_string不适用于数组。
所以这是逃避这样一个$ _POST变量的唯一解决方案。
function sanitate($array) {
foreach($array as $key=>$value) {
if(is_array($value)) { sanitate($value); }
else { $array[$key] = mysql_real_escape_string($value); }
}
return $array;
}
sanitate($_POST);
要消毒或验证任何INPUT_GET
,INPUT_POST
,INPUT_COOKIE
,INPUT_SERVER
或INPUT_ENV
,你可以使用
filter_input_array
- 获取外部变量并可选择过滤它们可以使用回调进行过滤,因此您可以提供mysql_real_escape_string
。
这种方法不允许对$_REQUEST
进行过滤,因为当数据在任何其他超全球中可用时,you should not work with $_REQUEST
。这可能是不安全的。
该方法还要求您命名输入键,因此它不是通用的批量过滤。如果您想要通用批量过滤,请使用array_map
或array_walk
或array_filter
,如本页其他地方所示。
另外,为什么你使用旧的mysql扩展而不是mysqli(我的改进)扩展。 mysqli扩展将为您提供transactions,multiqueries和prepared statements的支持(无需转义)所有功能都可以使您的数据库代码更加可靠和安全。
如果您使用mysqli扩展,并且您想要转义所有GET变量:
$escaped_get = array_map(array($mysqli, 'real_escape_string'), $_GET);
作为替代方案,我建议你使用PHP7 input filters,它提供了sql转义的快捷方式。我本身不推荐它,但它不遗余力地创建本地化变量:
$_REQUEST->sql['kkld']
哪个可以在SQL查询字符串中内联使用,如果忘记它,可以发出额外的警告:
mysql_query("SELECT x FROM y WHERE z = '{$_REQUEST->sql['kkld']}'");
它在语法上有问题,但允许您只转义那些真正需要它的变量。或者模仿你要求的东西,使用$_REQUEST->sql->always();