#php #символы #html #mysql
Каким образом необходимо обрабатывать текст и html-код для записи в базу MySQL? Какая
схема?
Перерыл интернет, везде совет для записи в базу использовать mysql_real_escape_string(),
и больше вроде ничего не нужно.
Но как быть со спец-мисволами html? К примеру "⇔" при вставке в форму отображается
как символ, а не как html-код сивола. Соответственно при записи в базу, он превращается
в "?"
Как я понимаю необходимо обрабатывать текст вот так перед вставкой:
$inputText = htmlentities($inputText, ENT_NOQUOTES, 'UTF-8');
$inputText = mysql_real_escape_string($inputText);
Соответственно при выводе из базы на отображение необходимо обрабатывать текст вот так:
$inputTex = html_entity_decode($inputTex);
Такой алгоритм правильный или надо делать как-то по-другому?
Кодировка сайта utf8.
Ответы
Ответ 1
Вопрос очень простой, но в то же время очень характерный.
В нем отлично собраны наиболее популярные заблуждения начинающих пользователей РНР.
Попробуем в них разобраться.
Хранение
Самое первое, что надо научиться - это не путать хранение данных и их использование
в SQL запросах. Это совершенно разные вещи. По поводу хранения следует понимать, что
храниться в БД могут абсолютно любые данные, и при этом храниться они должны как есть.
То есть, для хранения их никак, вообще никак обрабатывать не нужно.
Следовательно, отвечая на поставленные в посте (не совсем корректные, как мы видим),
вопросы:
Как хранить какие-либо данные в БД? Данные должны храниться как есть.
Как обрабатывать данные для БД? Никак. Ни в коем случае никак обрабатывать нельзя.
Как хранить HTML? Никаких особенных действий ни для HTML, ни для любых других данных
производить не нужно. Все данные хранятся абсолютно одинаково.
Использование данных в SQL запросах.
А вот это уже совсем другой вопрос. Единственный, в ответ на который нам надо будет
что-то делать. Но при этом сами данные мы всё равно трогать не будем. Да-да! Даже для
помещения в SQL запрос мы никак данные обрабатывать не будем. Дело в том, что "совет
для записи в базу использовать mysql_real_escape_string()" - это просто феерическая
глупость, к сожалению, растиражированная в миллионах экземпляров.
А единственно правильный способ добавления данных в SQL запрос - это делать это через
плейсхолдеры.
То есть, чтобы использовать любые данные в SQL запросе, надо сначала на их месте
написать знаки вопроса:
INSERT INTO users (name, lastname) VALUES (?,?)
это, кстати, касается вообще всех запросов. SELECT мы пишем точно так же:
SELECT * FROM users WHERE name=?
после этого надо будет подготовить запрос, а потом выполнить его, передав переменные
отдельно. Вот как это происходит на примере PDO:
$stmt = $pdo->prepare("INSERT INTO users (name, lastname) VALUES (?,?)");
$stmt->execute(array($name, $lastame));
то есть, идея такая: если нам надо подставить в запрос какую-либо переменную, вместо
неё надо поставить знак вопроса. А саму переменную передать после.
Таким образом мы будем гарантированы от любых ошибок и неприятностей, поскольку РНР
сам обработает за нас все переменные и сделает это правильно.
Спец-символы HTML
Я думаю, что внимательный читатель уже уловил идею: HTML вообще никакого отношения
к БД не имеет. Ни малейшего. Это абсолютно разные вещи. То есть пользователю РНР никогда
не должна приходить в голову идея использовать функцию, в которой встречается слово
"HTML" для какой-либо работы с БД, а при работе с HTML - функцию, в которой встречается
слово "mysql".
Функции для работы с HTML следует применять для работы с HTML.
То есть, если мы собираемся выводить HTML текст в HTML, то мы его должны выводить
как есть.
Но если мы собираемся выводить в HTML текст, который не является HTML, мы должны
отформатировать его так, чтобы он нам случайно не попортил верстку. Обычно для этого
используется функция htmlspecialchars()
Кодировка
Если какой-либо символ сохраняется в виде знака вопроса, то это не проблема HTML
кодирования, а проблема кодировки, которая попросту не поддерживает данный символ.
Чтобы БД могла сохранять символы типа ⇔, у нее должна быть кодировка utf8. А также
РНР скрипт, устанавливая соединение с базой, должен выставлять кодировку этого соединения
в utf8. При этом отображая пользователю форму, должен выдавать НТТР заголовк Content-type
с кодировкой UTF-8.
И тогда все символы запишутся в целости и сохранности.