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

时间:2014-11-24 22:45:11

标签: php mysql

更新版本

<?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);
?>

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

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

错误:无法执行INSERT INTO电影(movie_original_name,movie_tr_name,movie_year)值(&#39;电影的名称&#39;,&#39;&#39;,&#39; 2014& #39)。您的SQL语法有错误;查看与您的MySQL服务器版本对应的手册,以获得正确的语法,以便使用附近的名称&#39;&#39;&#39;&#39; 2014&#39;)&#39;在第1行

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

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

2 个答案:

答案 0 :(得分:2)

您需要准备好您的陈述,这样您就不会受到SQL Injection攻击。为此,您应该使用mysqli prepared statements。您当前的代码看起来像预备语句

$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中,我已经用?&#39; s替换了你的变量,这让它们稍后被绑定。在我的bind_param方法中,第一个参数是您要绑定的变量数,以及它们是什么数据类型。每个变量都有一个字符,它们都是所有字符串,因此字符是&#34; s&#34;。如果要绑定整数和字符串,可以使用

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

注意&#34; sis&#34;的顺序。匹配传递它的顺序,字符串然后整数然后再次字符串。根据{{​​3}},您可以传入四种不同的类型,每种类型都有自己的字符

  • s for string
  • i for integer
  • d for double
  • b for blob

这是对绑定参数的简短解释。您遇到的问题来自于您的变量不会被转义或绑定,从而使它们可以注入。这将解决您的问题并使您的代码更安全。

注意:正如@bcintegrity指出的那样,这并不是安全的全部目的。当您回显用户输入的数据以便停止PHP Manual时,您可能会想要使用htmlspecialchars()进行调查,这样可能会非常危险而无法修补

答案 1 :(得分:1)

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

以下是一个例子:

$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);

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

$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。两者都可以接受。