2014-11-24 2 views
0

обновлённая версияНевозможно добавить записи в 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 (movie_original_name, movie_tr_name, movie_year) VALUES ('Movie's Name', '', '2014'). У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с именем '', '', '2014') 'в строке 1

(Я удалил свои комментарии, поэтому номер строки будет отличаться)

Думаю, я должен использовать трюк, чтобы убежать от персонажей, но не мог понять, как это сделать.

+1

Использование PDO. Подготовьте отчет. – Jonast92

+0

Это синтаксический разбор, а не ошибка времени выполнения. Итак, что такое ** настоящий ** код для строк 41-43? – zerkms

+0

@ Jonast92: хотя ваша точка действительна - OP имеет ошибку разбора – zerkms

ответ

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, я заменил переменные с? С, это давайте их обязательность в дальнейшем. В моем методе bind_param первым параметром является количество переменных, которые вы связываете, и какие типы данных они есть. Для каждой переменной есть один символ, и все они являются строками, поэтому символ «s». Если вы хотите, чтобы связать целые числа и строки, вы должны использовать

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

Обратите внимание, как порядок «НВС» соответствует порядку, что проезжал, строка, то целое число, то строку снова. Согласно PHP Manual, есть четыре различных типа вы можете передать, каждый со своими персонажами

  • s для строки
  • I целочисленного
  • г для двойного
  • б для сгустка

Так что это краткое объяснение связанных параметров. Проблема, с которой вы сталкиваетесь, связана с тем, что ваши переменные не сбрасываются или не связаны, оставляя их открытыми для инъекций. Это устранит вашу проблему и сделает ваш код немного более безопасным.

Примечание: Как указано в @bcintegrity, это не все для защиты. Вы хотите посмотреть на использование htmlspecialchars(), повторяя свои данные, которые были введены пользователями, чтобы остановить XSS (Cross Site Scripts), что может быть очень опасно, если вы не сможете их исправить.

1

Сделать приоритетом использование подготовленных операторов. Подготовленные утверждения просто отправляют запрос отдельно от значений, поэтому db знает, что значения не должны выполняться как код.Подготовленные заявления избежать значения автоматически :)

Вот пример:

$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. Оба приемлемы.

+0

Это решило мою проблему, спасибо. Но теперь у меня проблемы с турецкими персонажами из-за htmlspecialchars. Как я могу это решить? Я также смотрю @ решение Гарета. – salep

+0

Рад помочь! У меня была такая же проблема. Я избегал использовать подготовленные заявления, потому что думал, что будет трудно учиться, но я ошибся. Поиск Google помогает найти кучу «как это» на эту тему. Повеселись! Обязательно принимайте ответ :) – bcintegrity

+0

Попробуйте использовать htmlentities() вместо htmlspecialchars(). Чтобы быть ясным, это необходимо только для значений, которые отражены на странице, а не параметров (значений в запросе). – bcintegrity

Смежные вопросы