jessepinkman010101
@jessepinkman010101
Варю синий код

Как очищать текст в php?

Привет, помогите разобраться.

На бэк приходит текст который нужно сохранить в базу. Использую pdo, но записи c html тегами все равно попадают туда. Индус советует использовать такую универсальную функцию

function my_trim($var) {
	$var =  trim($var);
	$var =  htmlspecialchars($var);
	$var =  stripcslashes($var);
	$var =  strip_tags($var);
	return $var;	
}	

$trimmed = my_trim($_POST['name']);


А что можете Вы посоветовать, какие есть актуальные способы, что бы не городить, то что предложил Индус.

Спасибо
  • Вопрос задан
  • 1673 просмотра
Решения вопроса 1
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Никак не очищать.

На самом деле этот вопрос встречается довольно часто. Вот например популярный ответ на Stack Overflow, который подробно разбирает этот распространённое заблуждение: https://stackoverflow.com/a/3126175. И основная мысль там:

Понятие такой генерализованной "очистки данных" изначально бессмысленное и вредное.

Особенно такой вот индусской функцией, которая сама по себе - пример редкого идиотизма: сначала заменяем символы < и > на HTML сущности... а потом бодро пытаемся вырезать HTML теги. Которых к этому моменту в тексте не останется ни одного!
Или функция stripcslashes, которая здесь вообще ни к селу, ни к городу. Если я хочу написать сочетание \n, то с какой стати эта функция будет заменять его на перевод строки?
Всё что можно оставить из этого безумного набора - это trim(). Да и то не всегда. Как правильно заметил Rsa97, могут быть случаи, когда лидирующие пробелы имеют значение, например, при выводе форматированного кода. Кстати, этим как раз грешит Хабр. Если запостить код с отступами, то первый будет "съеден"!


Очистка

Любая "очистка" (хотя правильнее говорить про форматирование), имеет смысл только в определённом контексте.
И поэтому "очищать" надо только адресно, строго перед использованием в том или ином конкретном случае.

Например, базе данных ни жарко, ни холодно от наличия HTML тегов.
А проблемы могут начаться только при выводе данных в HTML. Но если мы будем предотвращать эти проблемы заранее, то просто попортим кучу данных. Поэтому форматировать данные для использования в контексте отрисовки HTML следет строго перед этой отрисовкой. То есть при выводе.
Что и делают все популярные РНР шаблонизаторы автоматически.
То есть вручную колупаться с "очисткой" вообще не нужно.

Больше того, "очистка" HTML поможет данным, выводимым в яваскрипт, как мёртвому припарки. То есть опять же - всегда надо понимать, в какой именно контекст мы выводим данные, и форматировать соответствующим образом. В частности любые данные передавать в яваскрипт только через json_encode()

И таких контекстов неисчислимое множество. Например, если мы используем переменную для передачи параметров в консольный скрипт, то надо обязательно обрабатывать её через escapeshellarg(). Если в регулярку - то preg_quote(). Имя файла для инклюда из переменной (хотя так делать вообще не стоит) надо хотя бы обрабатывать через basename(). И так далее.

Валидация

Если же наличие HTML тегов в поступающих данных противоречит техническому заданию, то надо заниматься не "очисткой", а валидацией: проверить регулярным выражением, есть ли в строке HTML теги. И если есть, то вернуть пользователю с сообщением об ошибке.

Защита БД

И кстати, по поводу "использую pdo".
На всякий случай уточню, что само по себе использование PDO не защищает ни от каких проблем
Важно помнить, что защита - это когда в базу данных отправляется строго константная строка запроса, полностью на 100% составленная из значений, прописанных в коде РНР, и в ней не используется ни одно значение, пришедшее в код извне. Причем PDO помогает здесь только наполовину, позволяя использовать в запросе подстановки вместо самих данных.
Но при этом для всех остальных частей запроса - например имен полей - у ПДО нет никакой защиты и её надо организовывать самостоятельно. Либо проверяя по белому списку, лабо, по крайней мере, прогоняя через регулярку.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы