查看以下方法。如果在文本框中输入的值为\ mysql_real_escape_string将返回duble反斜杠,但preg_replace将返回只有一个反斜杠的SQL。我对正则表达不太好,所以请帮忙。
$sql = "INSERT INTO tbl SET val='?'";
$params = array('someval');
public function execute($sql, array $params){
$keys = array();
foreach ($params as $key => $value) {
$keys[] = '/[?]/';
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
$paramsEscaped[$key] = mysql_real_escape_string(trim($value));
}
$sql = preg_replace($keys, $paramsEscaped, $sql, 1, $count);
return $this->query($sql);
}
答案 0 :(得分:1)
最好使用预备语句。查看更多信息http://www.php.net/manual/en/pdo.prepared-statements.php
答案 1 :(得分:1)
对我来说,基本上看起来你正在重新发明轮子,你的概念有一些严重的缺陷:
get_magic_quotes_gpc
。此功能已损坏。你不应该对它进行编码。而是让您的应用程序要求关闭它。mysql_real_escape_string
需要数据库链接标识符才能正常工作。你没有提供任何。这是一个严重的问题,你应该改变你的观念。但是,让我们这样做,但只是不要使用preg_replace
来完成这项工作。这是出于各种原因,但尤其是,?
的第一种模式导致用第一个参数替换所有内容。处理错误情况(例如太少或太多的参数/占位符)是不灵活的。另外想象一下,你插入的字符串也包含一个?
字符。它会破坏它。相反,需要跳过已处理的部分以及替换部分(Demo of such)。
为此你需要经历,把它拆开并处理它:
public function execute($sql, array $params)
{
$params = array_map(array($this, 'filter_value'), $params);
$sql = $this->expand_placeholders($sql, $params);
return $this->query($sql);
}
public function filter_value($value)
{
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
$value = trim($value);
$value = mysql_real_escape_string($value);
return $value;
}
public function expand_placeholders($sql, array $params)
{
$sql = (string) $sql;
$params = array_values($params);
$offset = 0;
foreach($params as $param)
{
$place = strpos($sql, '?', $offset);
if ($place === false)
{
throw new InvalidArgumentException('Parameter / Placeholder count mismatch. Not enough placeholders for all parameters.');
}
$sql = substr_replace($sql, $param, $place, 1);
$offset = $place + strlen($param);
}
$place = strpos($sql, '?', $offset);
if ($place === false)
{
throw new InvalidArgumentException('Parameter / Placeholder count mismatch. Too many placeholders.');
}
return $sql;
}
现有预备陈述的好处是,它们确实有效。你应该考虑使用它们。对于这样的游戏很不错,但是你最终需要处理更多的情况,并且重新使用由数千名其他用户测试的现有组件要容易得多。