одинарные кавычки в SQL Query - PullRequest
0 голосов
/ 21 декабря 2009

Я пишу php-скрипт, который используется для обновления базы данных, но он выдает ошибки, когда я пытаюсь выполнить запрос, он возвращает ошибку в соответствии с

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'id=15"' at line 1

Там, где написано «Использовать рядом», отображается часть запроса после того, как в данных есть пробел. Я предполагаю, что мне нужно поместить одинарные кавычки, где данные к запросу из переменных php, но когда я пытаюсь вставить их (даже без кавычек), я получаю ошибки синтаксического анализа из сценария

SQL-запрос

    mysql_query("UPDATE Videos SET Title=".$_POST['Title'].", Preacher=".$_POST['Preacher'].", Date=".$_POST['Date'].", Service=".$_POST['Service'].", File=".$_POST['File'].", Description=".$_POST['Description']."WHERE id=".$_GET['vid_id']."\"") or die(mysql_error());

Заранее благодарен за любую помощь

Ответы [ 5 ]

4 голосов
/ 21 декабря 2009

mysql_real_escape_string () и sql инъекции уже упоминались.
Но прямо сейчас ваш скрипт (кропотливо) должен смешать оператор SQL с данными / параметрами, и на следующем шаге сервер MySQL должен отделить данные от оператора.
Используя (на стороне сервера) подготовленные операторы обе «части» вашего запроса отправляются отдельно, и анализатор sql (вашего сервера MySQL) никогда не может «запутаться» в том, где заканчивается оператор и начинаются данные.

Модуль php-mysql не знает подготовленных операторов, но php-mysql i и PDO do.

$pdo = new PDO('mysql:host=localhost;dbname=test', '...', '...'); 
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

$stmt = $pdo->prepare('
  UPDATE
    Videos
  SET
    Title=:title ,
    Preacher=:preacher ,
    Date=:date ,
    Service=:service ,
    File=:file ,
    Description=:description
  WHERE
    id=:id
');
$stmt->bindParam(':title', $_POST['title']);
$stmt->bindParam(':preacher', $_POST['preacher']);
$stmt->bindParam(':date', $_POST['date']);
$stmt->bindParam(':service', $_POST['service']);
$stmt->bindParam(':file', $_POST['file']);
$stmt->bindParam(':description', $_POST['description']);
$stmt->bindParam(':id', $_GET['id']); // really _GET?
$stmt->execute();

Может показаться слишком много, если использовать $ stmt только для одной операции. Но учтите, что в противном случае вы должны вызывать mysql_real_escape_string () для каждого параметра.

1 голос
/ 21 декабря 2009

Вам необходимо правильно экранировать переменные и заключить их в одинарные кавычки:

mysql_query("UPDATE
                Videos
            SET
                Title = '".mysql_real_escape_string($_POST['Title'])."',
                Preacher = '".mysql_real_escape_string($_POST['Preacher'])."', 
                Date = '".mysql_real_escape_string($_POST['Date'])."',
                Service = '".mysql_real_escape_string($_POST['Service'])."',
                File = '".mysql_real_escape_string($_POST['File'])."',
                Description = '".mysql_real_escape_string($_POST['Description'])."'
            WHERE
                id = '".mysql_real_escape_string($_GET['vid_id'])."'")
or die(mysql_error());

Без правильного экранирования переменных вы становитесь уязвимыми для атак SQL-инъекций .

EDIT

Чтобы упростить вышесказанное, вы можете сделать несколько трюков:

// Apply mysql_escape_string to every item in $_POST
array_map('mysql_real_escape_string', $_POST);
// Get rid of $_POST, $_POST['Title'] becomes $p_Title
extract($_POST, EXTR_PREFIX_ALL, 'p_');

// Use sprintf to build your query
$query = sprintf("UPDATE
                Videos
            SET
                Title = '%s',
                Preacher = '%s', 
                Date = '%s',
                Service = '%s',
                File = '%s',
                Description = '%s'
            WHERE
                id = '%s'",
            $p_Title,
            $p_Preacher,
            $p_Service,
            $p_File,
            $p_Description,
            mysql_real_escape_string($_GET['vid_id']));

mysql_query($query) or die(mysql_error());

Обратите внимание, что смешивать переменные $ _POST и $ _GET не рекомендуется. Вы должны указать идентификатор обновления через скрытое поле ввода в форме.

1 голос
/ 21 декабря 2009

Поскольку вы используете DB API напрямую (без уровня абстракции БД), лучшим решением будет использование функции escape DB.

Просто используйте mysql_real_escape_string().

<?php
// Your query
$query = sprintf("UPDATE Videos SET Title='%s', preacher='%s', Date='%s', "
                     ."Service='%s', File='%s', Description='%s' WHERE id='%s'",
                 mysql_real_escape_string($_POST['Title']),
                 mysql_real_escape_string($_POST['Preacher']),
                 mysql_real_escape_string($_POST['Date']),
                 mysql_real_escape_string($_POST['Service']),
                 mysql_real_escape_string($_POST['File']),
                 mysql_real_escape_string($_POST['Description']),
                 mysql_real_escape_string(($_GET['vid_id']));
?>

В качестве бонуса вы получите действительно улучшенную защиту от SQL INJECTION атакует ваш предыдущий код был подвержен.

В случае, если вы просто избежите косой черты, вам снова придется использовать функции php / mysql addslashes() выполнит эту работу в этом случае.

0 голосов
/ 21 декабря 2009

УДАЛИТЬ \ ", от:

id=".$_GET['vid_id']."\""
0 голосов
/ 21 декабря 2009

Почему вы ставите \" в конце, это ставит " в конец вашего SQL, но у вас его нет в начале?

Попробуйте это:

mysql_query("UPDATE Videos SET Title=".$_POST['Title'].", Preacher=".$_POST['Preacher'].", Date=".$_POST['Date'].", Service=".$_POST['Service'].", File=".$_POST['File'].", Description=".$_POST['Description']."WHERE id=".$_GET['vid_id']) or die(mysql_error());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...