PHP preg_replace() 在字符串包含单引号时返回空值,否则有效
PHP preg_replace() is returning null when string includes a single quote but works otherwise
下面的代码非常简单。 PHP 使用 POST 从表单中收集一个字符串,然后我正在寻找 trim 和 运行 一个 preg_replace 函数,它将去除任何特殊字符,除了单引号或连字符。请记住,整个代码在正则表达式中不涉及引号或连字符的情况下工作正常。
preg_replace("/[^\w\s'-]/", '', $raw_lemurName);
然后将那些干净的变量插入到数据库中。 Apache/2.4.37. MariaDB.
当我将 lemurName 设为 "Diademed Sifaka<>!" 之类的字符串时,它起作用了,并且 returns 'Diademed Sifaka'.
然而,当我将其设为包含单引号的字符串时,如 "Coquerel's Sifaka" 操作未完成且未插入任何信息。
我自己测试了正则表达式,它工作正常,似乎当你开始涉及 SQL 和数据库时它就停止工作了。
值得注意:
- 使用 phpMyAdmin。如果我在那里插入字符串,它就可以正常工作,所以我的数据库可以保存这些值。
- 尝试在不同的地方使用 mysqli_real_escape_string(),但没有成功,也许是做错了。
- 仔细阅读,我认为这与 SQL 不允许插入带有单引号的字符串以及服务器在 post 方法中自动转义单引号有关。
有什么想法吗?
非常感谢。
$raw_lemurName = isset($_POST['lemurName']) ? $_POST['lemurName'] : null;
$raw_lemurLat = isset($_POST['lemurLat']) ? $_POST['lemurLat'] : null;
$raw_family = isset($_POST['family']) ? $_POST['family'] : null;
//下面的正则表达式似乎搞砸了
$c_lemurName = trim(preg_replace("/[^\w\s'-]/", '', $raw_lemurName));
$c_lemurLat = strtolower(trim(preg_replace('/[^\w\s]/', '', $raw_lemurLat)));
$c_family = trim(preg_replace('/[^\w\s]/', '', $raw_family));
if (isset($_POST['submit'])) {
$query1 = "INSERT INTO `lemurs` (`id`, `lemur`, `latin`, `family`) VALUES (NULL, '$c_lemurName','$c_lemurLat','$c_family')";
$run_query = mysqli_query($connection, $query1);
if($run_query){
echo "Data has been inserted";
} else {
echo "Operation Unsuccessful";
}
header("location: index.php");
return;
}
这是一个标准的 SQL 注入问题。问题源于您将这些变量添加到查询中的方式:
$query1 = "INSERT INTO `lemurs` (`id`, `lemur`, `latin`, `family`) VALUES (NULL, '$c_lemurName','$c_lemurLat','$c_family')";
想想这里到底发生了什么,你所做的只是将字符串连接在一起,所以如果 $c_lemurName
是 '
- 那么你的 SQL 将变成:
[...] VALUES (NULL, ''', '[...]
这实际上真正让您了解所谓的 "injection attack"。基本上,恶意用户可以将 $c_family
设置为类似... ');drop table lemurs;--
- 你现在正在执行一个插入语句,然后是一个 drop table 语句,其余的 SQL 作为评论。
有几种方法可以解决这个问题,最常被建议的方法是查看参数化查询——对于 mysqli 库来说,这必须通过准备好的语句来完成。 PHP docs page.
上有一个这样的例子
同时替换第二个参数区域中的单引号。使用这个。
preg_replace("/[^\w\s'-]/", "", $raw_lemurName);
希望有用
下面的代码非常简单。 PHP 使用 POST 从表单中收集一个字符串,然后我正在寻找 trim 和 运行 一个 preg_replace 函数,它将去除任何特殊字符,除了单引号或连字符。请记住,整个代码在正则表达式中不涉及引号或连字符的情况下工作正常。
preg_replace("/[^\w\s'-]/", '', $raw_lemurName);
然后将那些干净的变量插入到数据库中。 Apache/2.4.37. MariaDB.
当我将 lemurName 设为 "Diademed Sifaka<>!" 之类的字符串时,它起作用了,并且 returns 'Diademed Sifaka'.
然而,当我将其设为包含单引号的字符串时,如 "Coquerel's Sifaka" 操作未完成且未插入任何信息。
我自己测试了正则表达式,它工作正常,似乎当你开始涉及 SQL 和数据库时它就停止工作了。
值得注意:
- 使用 phpMyAdmin。如果我在那里插入字符串,它就可以正常工作,所以我的数据库可以保存这些值。
- 尝试在不同的地方使用 mysqli_real_escape_string(),但没有成功,也许是做错了。
- 仔细阅读,我认为这与 SQL 不允许插入带有单引号的字符串以及服务器在 post 方法中自动转义单引号有关。
有什么想法吗?
非常感谢。
$raw_lemurName = isset($_POST['lemurName']) ? $_POST['lemurName'] : null;
$raw_lemurLat = isset($_POST['lemurLat']) ? $_POST['lemurLat'] : null;
$raw_family = isset($_POST['family']) ? $_POST['family'] : null;
//下面的正则表达式似乎搞砸了
$c_lemurName = trim(preg_replace("/[^\w\s'-]/", '', $raw_lemurName));
$c_lemurLat = strtolower(trim(preg_replace('/[^\w\s]/', '', $raw_lemurLat)));
$c_family = trim(preg_replace('/[^\w\s]/', '', $raw_family));
if (isset($_POST['submit'])) {
$query1 = "INSERT INTO `lemurs` (`id`, `lemur`, `latin`, `family`) VALUES (NULL, '$c_lemurName','$c_lemurLat','$c_family')";
$run_query = mysqli_query($connection, $query1);
if($run_query){
echo "Data has been inserted";
} else {
echo "Operation Unsuccessful";
}
header("location: index.php");
return;
}
这是一个标准的 SQL 注入问题。问题源于您将这些变量添加到查询中的方式:
$query1 = "INSERT INTO `lemurs` (`id`, `lemur`, `latin`, `family`) VALUES (NULL, '$c_lemurName','$c_lemurLat','$c_family')";
想想这里到底发生了什么,你所做的只是将字符串连接在一起,所以如果 $c_lemurName
是 '
- 那么你的 SQL 将变成:
[...] VALUES (NULL, ''', '[...]
这实际上真正让您了解所谓的 "injection attack"。基本上,恶意用户可以将 $c_family
设置为类似... ');drop table lemurs;--
- 你现在正在执行一个插入语句,然后是一个 drop table 语句,其余的 SQL 作为评论。
有几种方法可以解决这个问题,最常被建议的方法是查看参数化查询——对于 mysqli 库来说,这必须通过准备好的语句来完成。 PHP docs page.
上有一个这样的例子同时替换第二个参数区域中的单引号。使用这个。
preg_replace("/[^\w\s'-]/", "", $raw_lemurName);
希望有用