如果记录包含撇号,则无法将记录添加到 MySQL


Can't add records to MySQL if the record contains an apostrophe

更新版本

<?php
$link = mysqli_connect("localhost", "root", "root", "metadata");
mysqli_set_charset($link, "utf8");
// Check connection
if($link === false){
  die("ERROR: Could not connect. " . mysqli_connect_error());
}
// my form located in index.php posts the data here.
$add_movie_original_name = $_POST['movie_original_name'];
$add_movie_tr_name = $_POST['movie_tr_name'];
$add_movie_year = $_POST['movie_year'];
$sql = "INSERT INTO movie(movie_original_name,movie_tr_name,movie_year) VALUES('$add_movie_original_name','$add_movie_tr_name','$add_movie_year')";
if(mysqli_query($link, $sql)){
  echo "Records added successfully.";
} else{
  echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
}
// close connection
mysqli_close($link);
?>

如果其中有撇号,我无法添加记录。例如,无法添加山姆大叔的

这是我得到的错误。我尝试添加一个名为"电影名称"的电影

错误:无法执行插入到影片(movie_original_name,movie_tr_name,movie_year)值("影片名称","2014")。您的 SQL 语法有误;检查与您的MySQL服务器版本相对应的手册,了解在第1行的"Name",","2014")附近使用的正确语法

(我删除了我的评论,所以行号会有所不同)

我想我应该用一个技巧来逃避角色,但找不到办法。

你需要准备你的语句,这样你就不会容易受到SQL注入攻击。为此,您应该使用 mysqli 预准备语句。您当前的代码将如下所示,作为预准备语句

$mysqli = new Mysqli("localhost", "root", "root", "metadata");
$statement = $mysqli->prepare("INSERT INTO movie(movie_original_name,movie_tr_name,movie_year) VALUES('?','?','?')");
$statement->bind_param('sss', $add_movie_original_name, $add_movie_tr_name, add_movie_year);
$statement->execute();

请注意,在实际的 SQL 中,我如何将您的变量替换为 ?s,这让他们以后被绑定。在我的bind_param方法中,第一个参数是要绑定的变量数以及它们是什么数据类型。每个变量都有一个字符,它们都是字符串,因此该字符为"s"。如果要绑定整数和字符串,请使用

$statement->bind_param('sis', $string1, $int1, $string2);

请注意"sis"的顺序如何与传递它的顺序匹配,字符串然后是整数,然后再次字符串。根据PHP手册,您可以传入四种不同的类型,每种类型都有自己的字符。

  • s 表示字符串
  • i 表示整数
  • D 代表双倍
  • b 表示斑点

所以这是对绑定参数的简短解释。你遇到的问题来自于你的变量没有被转义或绑定,让它们被注入。这将解决您的问题并使您的代码更加安全。

注意:正如@bcintegrity所指出的,这并不是安全的全部。在回显用户输入的数据时,您将需要研究使用 htmlspecialchars() 以停止 XSS(跨站点脚本),如果不修补这可能非常危险。

优先使用预准备语句。预准备语句只是将查询与值分开发送,因此数据库知道这些值不会作为代码运行。预准备语句自动转义值:)

下面是一个示例:

$sqli = @mysqli_connect("localhost", "root", "root","metadata");
if (!$sqli) {die("Can not connect to the database: " . mysqli_connect_error());}
$result = "INSERT INTO `movie`(movie_original_name,movie_tr_name,movie_year) VALUES (?,?,?)";
$stmt = mysqli_prepare($sqli, $result);
mysqli_stmt_bind_param($stmt,"sss",$_POST['movie_original_name'],$_POST['movie_tr_name'],$_POST['movie_year']);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);

如果将值回显到页面上,请务必使用 htmlspecialchars() 以防止 XSS:

$original_name_onscreen = htmlspecialchars($_POST['movie_original_name']);
$tr_name_onscreen = htmlspecialchars($_POST['movie_tr_name']);
$year_onscreen = htmlspecialchars($_POST['movie_year']);

注意:@Gareth Parker的例子是面向对象风格,类似于PDO,而我的例子是过程风格,类似于MySQL。两者都是可以接受的。