В посте преобразуйте в сущности теги, которые не разрешены, и оставьте теги разрешенными
У меня есть форма, где пользователь может опубликовать глобальное уведомление в системе (чтобы его могли увидеть другие пользователи).
Система выводит HTML напрямую из БД (когда пользователь хочет увидеть уведомление).
Я бы хотел, чтобы некоторые html-теги оставались нетронутыми, а остальные - с применением htmlspecialchars().
Я уже пытался подать заявку
str_replace($search, $replace, htmlspecialchars($str))
стратегия, но, похоже, очень медленно. Слишком медленно, на самом деле. И также это не безопасно, что всегда будет работать, есть ли альтернатива для этого?
Я хотел что-то, что выполняло работу strip_tags(), за исключением того, что вместо чередования тегов он применял бы htmlspecialchars к недопустимым тегам.
ДОБАВИТЬ (ed) информация (по запросу):
$ str может быть любого размера, о котором вы только можете подумать. Я подумал об использовании большой строки (1M символов (сгенерированных случайным образом с некоторыми разрешенными и некоторыми недопустимыми тегами внутри. Все теги имели атрибуты) по причине тестирования одного из худших сценариев С логикой: если это работает так, то должно работать для более простых случаев.
Серверу потребовалось 5 секунд для полной обработки str_replace (с помощью htmlspecialchars). Этот тест был сделан на моем компьютере с процессором 2 ГГц и оперативной памятью DDR3.
$search и $replace имеют в общей сложности 7 замен. Тем не менее они не всегда работают. В некоторых случаях $search дает ложные срабатывания или ложные отрицания.
Чтобы уточнить, я применяю эти изменения при сохранении в БД, а не при извлечении из БД.
2 ответа
Вы можете попробовать этот код (должен быть улучшен):
function callback(array $matches) {
return htmlspecialchars_decode($matches[0]);
}
$str = 'some <i>string</i> <b>with</b> tags '
. '<a href="#">some link</a> '
. '<img alt="" src="http://sstatic.net/stackru/img/favicon.ico"/><hr/>';
$str = htmlspecialchars($str);
$str = preg_replace_callback('#(<(i|a)(?: .+?)?>.*?</(\1)>|<(?:img)(?: .*?)?/>)#', 'callback', $str);
echo $str;
Регулярное выражение ищет (должно выглядеть) для 2 типов строк:
<tag attributes>content</tag>
, сtag
часть одинакова для открытия закрывающего тега, иattributes
а такжеcontent
быть необязательным<tag attributes/>
, сattributes
быть необязательным
Теги перечислены в (i|a)
часть для <tag></tag>
типы тегов и (?:img)
за <tag/>
типы тегов.
Если он находит подходящие теги, он передает содержимое callback()
функция, которая преобразует его обратно с помощью htmlspecialchars_decode()
, Это необходимо для декодирования кавычек и других закодированных символов в списке атрибутов.
Я не уверен, работает ли он во всех случаях, т. Е. Соответствует ли он всем необходимым тегам. Если это работает в целом, то шаблон и callback()
функция должна быть улучшена так, чтобы callback()
только декодирует <
, >
символы и список атрибутов; содержание тегов (т.е. some link
участие в <a href='#'>some link</a>
) не должен быть расшифрован.
str_replace
вместе с htmlspecialchars
Не медленный
Возможно, у вас есть узкое место где-то еще.