Проверка и обработка входящих данных является одной из распространённых задач в программировании. Язык PHP обычно используется для веб-приложений, поэтому здесь наиболее актуально удаление HTML тегов из текста, ведь именно они наиболее подверженны сторонним инъекциям. В данной статье я хочу напомнить Вам о старичке stip_tags() и его фишках, а также предложить решения для удаления секционных HTML тегов и ещё парочку полезных бонусов вдогонку.
И так. Основным нашим инструментом для удаления HTML тегов из текста является функция strip_tags (). Мы передаём ей строковое значение, а она удаляет из него HTML и PHP теги, например:
$s = "
Параграф.
Еще текст.";Этот пример выведет строку:
Параграф. Еще текст.
Примечательно здесь то, что у функции имеется и второй (не обязательный, но полезный) параметр, значением которого является строка с перечнем разрешенных HTML тегов, например:
$s = "
Параграф.
Еще текст.";Этот пример выведет строку:
Параграф.
Еще текст.По моему, очень удобно. Тем не менее, это не решает одну важную проблему - удаление секционных HTML тегов , например: script , noscript и style - они наиболее распространённые. Когда мне нужно убрать такие секционные теги, а также варианты начинающиеся с « < » и заканчивающиеся символом « > », я использую следующий PHP код:
$p = array(
""]*?>.*?"si",
""]*?>.*?"si",
""]*?>.*?"si",
"""si",
);
$r = array(" "," "," "," ");
$s = preg_replace($p, $r, $s);
Здесь переменная $p содержит массив регулярных выражений, а $r - массив соответствующей их замены (я использую пробелы) . Осталось лишь провести замену в строке, и мы уберём HTML мусор из текста.
Очевидно, что два выше приведённых решения можно совместить. В начале я использую замену через регулярные выражения, а потом strip_tags() и у меня получается своя функция nohtml() .
Напоследок хочу предложить Вам ещё несколько полезных решений. Так в тексте лучше заменить табуляцию пробелом, результат интерпретации того и другого в браузере идентичны, а хлопот будет меньше, например:
$s = str_replace("\t", " ", $s);
Если Вам не нужны переносы строк, их тоже можно заменить пробелами, например:
$s = str_replace(array("\n", "\r"), " ", $s);
От лишних же пробелов можно избавиться простым регулярным выражением, например:
$s = preg_replace("/\s+/", " ", $s);
$s = trim($s); // будет не лишним
На этом у меня всё. Спасибо за внимание. Удачи!
в 21:56 | Изменить сообщение |
У Вас в браузере заблокирован JavaScript. Разрешите JavaScript для работы сайта!
strip_tags(PHP 3 >= 3.0.8, PHP 4, PHP 5)
strip_tags - Удаляет HTML и PHP тэги из строки Описание string strip_tags (string str [, string allowable_tags])Эта функция возвращает строку str, из которой удалены HTML и PHP тэги. Для удаления тэгов используется автомат, аналогичный примененному в функции fgetss() .
Необязательный второй аргумент может быть использован для указания тэгов, которые не должны удаляться.
Замечание: Аргумент allowable_tags был добавлен в PHP 3.0.13 и PHP 4.0b3. С версии PHP 4.3.0 удаляются также HTML комментарии.
ВниманиеТак как strip_tags() не проверяет корректность HTML кода, незавершенные тэги могу привести к удалению текста, не входящего в тэги.
Пример 1. Пример использования strip_tags() $text = "Параграф.
Еще немного текста"; echo strip_tags($text); echo "\n\n-------\n"; // не удалятьEcho strip_tags($text, "
"); // Разрешаем ,, echo strip_tags($text, "");
Этот пример выведет:
Параграф. Еще немного текста -------
Параграф.
Еще немного текста
ВниманиеЭта функция не изменяет атрибуты тэгов, указанных в аргументе allowable_tags, включая style и onmouseover.
С версии PHP 5.0.0 strip_tags() безопасна для обработки данных в двоичной форме.
У данной функции есть существенный недостаток - это склейка слов при удалении тегов. Кроме этого функция имеет уязвимости. Альтернативная функция аналог strip_tags:
Смотрите также описание функции
С задачей очистки html от лишних тегов сталкиваются абсолютно все.
Первое, что приходит на ум, это использовать php-функцию strip_tags():
string strip_tags (string str [, string allowable_tags])
Функция возвращает строку, очищенную от тегов. В качестве аргумента allowable_tags
передаются теги, которые не надо удалять
. Функция работает, но, мягко говоря, неидеально. По ходу, там нет проверки на валидность кода, что может повлечь за собой удаление текста, не входящего в тэги.
Инициативные разработчики сложа руки не сидели — в сети можно найти доработанные функции. Хорошим примером является strip_tags_smart .
Применять или не применять готовые решения — личный выбор программиста. Так сложилось, что мне чаще всего не требуется "универсального" обработчика и бывает удобнее почистить код регулярками.
От чего зависит выбор того или иного способа обработки?
1. От исходного материала и сложности его анализа.
Если вам нужно обрабатывать достаточно простые htmp-тексты, без какой-либо навороченной верстки, ясные, как день:), то можно использовать стандартные функции.
Если в текстах есть определенные особенности, которые надо учесть, то тут-то и пишутся специальные обработчики. В одних может использоваться просто str_replace
. Например:
$s = array("’" => "’", // Right-apostrophe (eg in I"m)
"“" => "“", // Opening speech mark
"–" => "—", // Long dash
"â€" => "”", // Closing speech mark
"Ã " => "é", // e acute accent
chr(226) . chr(128) . chr(153) => "’", // Right-apostrophe again
chr(226) . chr(128) . chr(147) => "—", // Long dash again
chr(226) . chr(128) . chr(156) => "“", // Opening speech mark
chr(226) . chr(128) . chr(148) => "—", // M dash again
chr(226) . chr(128) => "”", // Right speech mark
chr(195) . chr(169) => "é", // e acute again
);
foreach ($s as $needle => $replace)
{
$htmlText = str_replace($needle, $replace, $htmlText);
}
Другие могут быть основаны на регулярных выражениях . Как пример:
Function getTextFromHTML($htmlText)
{
$search = array (""]*?>.*?"si", // Remove javaScript
""]*?>.*?"si", // Remove styles
""]*?>.*?"si", // Remove xml tags
"""si", // Remove HTML-tags
""([\r\n])[\s] "", // Remove spaces
""&(quot|#34);"i", // Replace HTML special chars
""&(amp|#38);"i",
""&(lt|#60);"i",
""&(gt|#62);"i",
""&(nbsp|#160);"i",
""&(iexcl|#161);"i",
""&(cent|#162);"i",
""&(pound|#163);"i",
""&(copy|#169);"i",
""(\d);"e"); // write as php
$replace = array ("",
"",
"",
"",
"\\1",
"\"",
"&",
"",
" ",
chr(161),
chr(162),
chr(163),
chr(169),
"chr(\\1)");
Return preg_replace($search, $replace, $htmlText);
}
(В такие минуты как никогда радует возможность preg_replace работать с массивами в качестве параметров). Массив вы при необходимости дополняете своими регулярками. Помочь в их составлении вам может, например, этот конструктор регулярных выражений . Начинающим разработчикам может быть полезной статья "All about HTML tags. 9 Regular Expressions to strip HTML tags" . Посмотрите там примеры, проанализируйте логику.
2. От объемов.
Объемы напрямую связаны со сложностью анализа (из предыдущего пункта). Большое количество текстов увеличивает вероятность, что, пытаясь предусмотреть и почистить все регулярками, вы можете что-нибудь да упустить. В этом случае подойдет метод "многоступенчатой" очистки. То есть очистить сначала, допустим, функцией strip_tags_smart (исходники на всякий случай не удаляем). Потом выборочно просматриваем некоторое количество текстов на выявление "аномалий". Ну и "зачищаем" аномалии регулярками.
3. От того, что надо получить в результате.
Алгоритм обработки может быть упрощен разными способами в зависимости от ситуации. Случай, описанный мной в одной из предыдущих статей , хорошо это демонстрирует. Напомню, текст там находился в div-е, в котором кроме него был еще div с "хлебными крошками", реклама адсенс, список похожих статей. При анализе выборки статей обнаружилось, что статьи не содержат рисунков и просто разбиты на абзацы с помощью . Чтобы не чистить "главный" див от посторонних вещей, можно найти все абзацы (с Simple HTML DOM Parser это очень просто) и соединить их содержимое. Так что прежде чем составлять регулярки для чистки, посмотрите, нельзя ли обойтись малой кровью.
Вообще, между сторонниками парсинга html-кода, основанного чисто на регулярных выражениях, и парсинга, в основе которого лежит анализ DOM-структуры документа, в сети разгораются настоящие холивары. Вот, например, на оверфлоу. Невинный с первого взгляда