В PHP при отправке строк в базу данных я должен заботиться о недопустимых символах с помощью htmlspecialchars() или использовать регулярное выражение?
Я работаю над формой, в которой пользователь может использовать недопустимые / специальные символы в строке, которая должна быть отправлена в базу данных. Я хочу экранировать / отрицать эти символы в строке и использовал htmlspecialchars (). Однако есть ли лучший / более быстрый метод?
6 ответов
Если вы отправляете эти данные в базу данных, обратите внимание на функции escape для вашей базы данных.
То есть для MySQL есть http://php.net/mysql_real_escape_string.
Эти escape-функции заботятся о любых символах, которые могут быть вредоносными, и вы по-прежнему будете получать ваши данные так же, как вы их вводите.
Вы также можете использовать подготовленные заявления, чтобы заботиться о данных:
$dbPreparedStatement = $db->prepare('INSERT INTO table (htmlcontent) VALUES (?)');
$dbPreparedStatement->execute(array($yourHtmlData));
Или немного больше объяснения:
$dbPreparedStatement = $db->prepare('INSERT INTO table (htmlcontent) VALUES (:htmlcontent)');
$dbPreparedStatement->execute(array(':htmlcontent' => $yourHtmlData));
Если вы хотите сохранить разные типы данных, используйте bindParam
чтобы определить каждый тип, то есть целое число может быть определено с помощью: $db->bindParam(':userId', $userId, PDO::PARAM_INT);
, Пример:
$dbPreparedStatement = $db->prepare('INSERT INTO table (postId, htmlcontent) VALUES (:postid, :htmlcontent)');
$dbPreparedStatement->bindParam(':postid', $userId, PDO::PARAM_INT);
$dbPreparedStatement->bindParam(':htmlcontent', $yourHtmlData, PDO::PARAM_STR);
$dbPreparedStatement->execute();
куда $db
ваш объект данных PHP (PDO) Если вы не используете его, вы можете узнать больше об этом в PHP Data Objects.
Для базы данных нет "нелегальных" символов. База данных, которая не может хранить некоторые символы, это чепуха. Есть некоторые служебные символы, такие как кавычки, используемые для разделения строк. Эти символы должны быть просто экранированы, а не уничтожены.
Чтобы отправить запрос в базу данных, у вас есть 2 варианта:
Создайте запрос обычным способом, чтобы он выглядел точно так же, как SQL-запрос, который вы можете запустить в консоли SQL.
Чтобы сделать это, нужно понять целый набор правил, а не просто "использовать mysql_real_escape_string".
Правила, такие как:- Строки должны быть заключены в кавычки и экранированы. Это единственное значение побега: это просто пробелы! (и некоторые другие символы - символ завершения строки и сам символ выхода). Без окружающих кавычек mysql_real_escape_string просто бесполезен.
- Числа должны быть приведены к его типу явно. Хотя числам данных можно угрожать точно так же, как и строкам, существуют некоторые числа, например параметры предложения LIMIT, которые нельзя экранировать и можно только привести.
Отправить запрос и данные отдельно.
Это наиболее предпочтительный способ, поскольку он может быть сокращен до "использования привязки". Все строки, числа и параметры LIMIT могут быть связаны - не беспокойтесь вообще.
Используя этот метод, ваш запрос с заполнителями отправляется в базу данных как есть, а связанные данные отправляются в отдельных пакетах, поэтому он не может вмешиваться. Это как разделение кода и данных. Вы отправляете свою программу (сам запрос) отдельно от данных.
Но!
Все сказанное выше охватывает только часть данных запроса.
Но иногда мы должны сделать наш запрос еще более динамичным, добавив операторы или идентификаторы.
В этом случае каждый динамический параметр должен быть жестко задан в нашем скрипте и выбран из этого набора.
Например, чтобы сделать динамическое упорядочение:
$orders = array("name","price","qty"); //field names
$key = array_search($_GET['sort'],$orders)); // see if we have such a name
$orderby = $orders[$key]; //if not, first one will be set automatically. smart enuf :)
$query = "SELECT * FROM `table` ORDER BY $orderby"; //value is safe
или динамический поиск:
$w = array();
$where = '';
if (!empty($_GET['rooms'])) $w[]="rooms='".mesc($_GET['rooms'])."'";
if (!empty($_GET['space'])) $w[]="space='".mesc($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mesc($_GET['max_price'])."'";
if (count($w)) $where="WHERE ".implode(' AND ',$w);
$query="select * from table $where";
В этом примере мы добавляем в запрос только данные, введенные пользователем, а не имена полей, которые все жестко заданы в скрипте. Для привязки алгоритм будет очень похожим.
И так далее.
Прежде всего, вы должны дезинфицировать вещи при отображении, а не перед вставкой в базу данных. Инъекции SQL - другая история, но, вероятно, не по теме.
Во-вторых, если вам не нужно, чтобы ваши пользователи вообще могли публиковать HTML, htmlspecialchars
это все, что тебе нужно. Он заботится обо всех специальных символах в HTML.
Я работаю над формой, в которой пользователь может использовать недопустимые / специальные символы в строке, которая должна быть отправлена в базу данных.
Пользователи могут пойти намного дальше, чем на самом деле.
Я хочу экранировать / отрицать эти символы в строке и использовал htmlspecialchars(). Тем не менее, я хотел бы знать, есть ли лучший / более быстрый метод.
Использовать очиститель HTML:
HTML Purifier - это стандартная библиотека HTML-фильтров, написанная на PHP. HTML Purifier не только удалит весь вредоносный код (более известный как XSS) с тщательно проверенным, но все же разрешающим белым списком.
Это не проблема, которую вы хотите решить самостоятельно. Для этого есть библиотеки, такие как HTML Purifier.
Вы не указали, какими могут быть эти недопустимые символы, но вам определенно следует использовать механизм API базы данных для экранирования данных. Например, если вы используете MySQL, используйте параметризованные операторы SQL PDO.