Вставка данных с помощью PHP в mysql, когда они содержат '

Я пишу много информации из файла XML в базу данных.

Все работает нормально, пока не натыкаюсь на поле с ' в описании, что вставка не проходит с ошибкой

Error

1064:You have an error in your SQL syntax; check the manual that

соответствует версии вашего сервера MySQL для правильного синтаксиса для использования рядом с 'хотел бы, чтобы вы тоже так думали. Мы будем рады, если вы посетите нас, чтобы посмотреть более 100 футов на линии 3.

Есть ли способ вставить это без сбоя? файл импорта может быть большим и регулярно меняться, поэтому я не могу искать и заменять символы ' внутри него.

Мое фактическое заявление PHP:

$query = mysql_query("REPLACE into list
(id, name, link, description, cost, date_added,type,myipaq,private,imgurl)
VALUES ('$id','$name','$link',"'$description'",'$cost','$date','$type','$myipaq','$private','$imgurl')");

заранее спасибо,

Грег


person kitenski    schedule 04.06.2010    source источник
comment
Я не парень PHP или парень MySQL, но вы можете сделать что-то вроде HTML ENCODE для его кодирования? Затем вы можете HTML DECODE его, чтобы снова отобразить его.   -  person Chase Florell    schedule 04.06.2010
comment
Ах... гуру говорят, что это называется mysql_real_escape_string - я думаю, что это та же концепция, что и html-кодирование   -  person Chase Florell    schedule 04.06.2010
comment
Почему $description заключен в двойные кавычки? Не вызовет ли это ошибок PHP, поскольку они не экранированы? И ошибки MySQL, если они экранированы?   -  person Brendan Long    schedule 04.06.2010
comment
решил с этим кодом перед MySQL, всем спасибо! $link_id = mysql_real_escape_string($link_id); $link_name = mysql_real_escape_string($link_name); $description = mysql_real_escape_string($description); $ metadesc = mysql_real_escape_string ($ metadesc); $link_created = mysql_real_escape_string($link_created); $link_modified = mysql_real_escape_string($link_modified); $ веб-сайт = mysql_real_escape_string ($ веб-сайт); $ стоимость = mysql_real_escape_string ($ стоимость);   -  person kitenski    schedule 04.06.2010
comment
НЕТ НЕТ НЕТ НЕТ. ИСПОЛЬЗУЙТЕ ПОДГОТОВЛЕННЫЕ ЗАЯВЛЕНИЯ. Подготовленные операторы — единственный пуленепробиваемый метод предотвращения атак с помощью SQL-инъекций, и вам просто не следует использовать что-либо еще. Поступать иначе — это просто очень плохая профессиональная практика.   -  person Cruachan    schedule 04.06.2010
comment
Также см. вопрос stackoverflow.com/questions/2353666/   -  person Cruachan    schedule 05.06.2010


Ответы (5)


Это относится к категории SQL-инъекций.

В PHP функция: mysql_real_escape_string используется для кодирования строки, чтобы ни одна из них не могла повлиять на оператор SQL, в который она может быть объединена.

поэтому убедитесь, что все ваши значения проходят через функцию mysql_real_escape_string, и все будет в порядке.

API REF: http://php.net/manual/en/function.mysql-real-escape-string.php

person Bob Fincheimer    schedule 04.06.2010
comment
Боже НЕТ. -1, несмотря на все плюсовые голоса. Настоящая escape-строка в лучшем случае - это липкий пластырь, ЕДИНСТВЕННЫЙ способ сделать это правильно - использовать подготовленные операторы. - person Cruachan; 04.06.2010
comment
поэтому убедитесь, что все ваши значения проходят через функцию mysql_real_escape_string, и все будет в порядке. Это утверждение вводит в заблуждение и не соответствует действительности. Это улучшение, но не совсем надежное решение. - person Cruachan; 05.06.2010

Просто передайте свои данные через mysql_real_escape_string()

person Fletcher Moore    schedule 04.06.2010
comment
Чтобы уточнить, передайте каждое значение через эту функцию, прежде чем создавать строку запроса. Вы не используете функцию для всего запроса. - person Marcus Adams; 04.06.2010
comment
Нет, используйте подготовленные операторы. -1 за предположение об обратном. - person Cruachan; 04.06.2010

Используйте мою удобную функцию денди:

function mysql_safe_string($value) {
    if(is_numeric($value))      return $value;
    elseif(empty($value))       return 'NULL';
    elseif(is_string($value))   return '\''.mysql_real_escape_string($value).'\'';
    elseif(is_array($value))    return implode(',',array_map('mysql_safe_string',$value));
}

function mysql_safe_query($format) {
    $args = array_slice(func_get_args(),1);
    $args = array_map('mysql_safe_string',$args);
    $query = vsprintf($format,$args);
    $result = mysql_query($query);
    if($result === false) echo '<div class="mysql-error"><strong>Error: </strong>',mysql_error(),'<br/><strong>Query: </strong>',$query,'</div>';
    return $result;
}

Вот так:

mysql_safe_query('INSERT INTO table VALUES (%s, %s, %s)', $val1, $val2, $val3);

И забудьте о том, чтобы цитировать или не цитировать свои строки, и писать mysql_real_escape_string дюжину раз.

person mpen    schedule 04.06.2010
comment
Неплохая идея. Что, если их массив уже содержит ,? - person Brendan Long; 04.06.2010
comment
@ Брендан: Что ты имеешь в виду? Если значения в массиве уже имеют конечные запятые? Они будут заключены в кавычки и вставлены в БД с запятыми... кто за это проголосовал? - person mpen; 04.06.2010
comment
Я проголосовал за, так как кто-то уже проголосовал против (и я думаю, что это отличная идея). Однако я спрашивал, что, если они получат этот массив: {"x","y",","}? Разве он не будет преобразован в: x, y,,, а затем, когда он будет преобразован обратно в массив: {"x","y","",""}? - person Brendan Long; 05.06.2010
comment
@Brendan: Ну, нет, это будет преобразовано в 'x','y',','. Он заключает в одинарные кавычки каждое значение (если это не целое число или пустая строка). - person mpen; 05.06.2010
comment
Единственное место, где я фактически использовал бит массива, - это запрос типа SELECT * FROM table WHERE val IN (%s). - person mpen; 05.06.2010

Единственный по-настоящему безопасный способ вставки, замены или взаимодействия с чем-либо в базе данных с помощью PHP — это использование подготовленных операторов. На самом деле больше нет оправдания тому, чтобы делать это по-другому. Экранирование строк с помощью mysql_real_escape_string даст вам некоторую защиту, но не является пуленепробиваемым.

Готовые отчеты даже не сложны. См. на них страницу руководства по PHP, там есть несколько оболочек для сделать жизнь еще проще, лично мне очень нравится оболочка codesense mysqli, и я использовать его какое-то время без проблем - это не сложнее, чем прямой PHP-код MySQL. EasyPDO тоже выглядит многообещающе.

Вы должны проверить соответствующий вопрос "PHP: Является ли mysql_real_escape_string "достаточным для очистки пользовательского ввода" для получения дополнительной информации о том, почему вам не следует лениться.

person Cruachan    schedule 04.06.2010
comment
@ Брендан, совсем не сложно использовать, особенно если вы используете обертку. Откровенно говоря, если чье-то кодирование находится на уровне, когда ему бросают вызов подготовленные операторы, они должны сдаться и заняться чем-то другим. - person Cruachan; 05.06.2010

Используйте: php.net/manual/en/function.addslashes.php

Addslashs предотвращают только это!

И если вы используете это, просто используйте

http://www.php.net/manual/en/function.stripslashes.php

чтобы удалить косые черты из вашей строки!

person Zuul    schedule 04.06.2010
comment
addslashes не защищает от внедрения: shiflett.org/ блог/2006/январь/ - person Brendan Long; 04.06.2010