Я хотел бы обработать свой пользовательский ввод, чтобы разрешить только определенные теги html, а также заменить другие своими объектами html, а также заменить теги без тегов. Например, если я хотел только разрешить теги <b>
и <a>
, тогда
allow_only("This is <b>bold</b> and this is <i>italic</i>. Moreover 2<3 and <a href='google.com'>this is a link</a>.","<b><a>");
должен производить
This is <b>bold</b> and this is <i>italic</i>. Moreover 2<3 and <a href='google.com'>this is a link</a>.
Как я могу это сделать в PHP? Я знаю strip_tags()
который может полностью удалить ненужные теги, и я знаю htmlspecialchars()
который может заменить все теги своими объектами html, но никого, где заменяются только те или htmlspecialchars()
теги. Как это можно сделать в PHP?
И если не существует «общего» способа сделать это, как я должен вообще обрабатывать пользовательский ввод, который может иметь правильный регулярный html, но также может иметь <
знаки и потенциально опасный код html?
Примените htmlspecialchars, а затем замените закодированные объекты на обычные объекты для заданного массива тегов
function allow_only($str, $allowed){ $str = htmlspecialchars($str); foreach( $allowed as $a ){ $str = str_replace("<".$a.">", "<".$a.">", $str); $str = str_replace("</".$a.">", "</".$a.">", $str); } return $str; } echo allow_only("This is <b>bold</b> and this is <i>italic</i>.", array("b"));
Это работает для простых тегов, возвращая «Это выделено жирным шрифтом, и это <i> курсив </ i>».
Как было указано, это не работает для тегов с атрибутами, но это делает:
function fix_attributes($match){ return "<".$match[1].str_replace('"','"',$match[2]).">"; } function allow_only($str, $allowed){ $str = htmlspecialchars($str); foreach( $allowed as $a ){ $str = preg_replace_callback("/<(".$a."){1}([\s\/\.\w=&;:#]*?)>/", fix_attributes, $str); $str = str_replace("</".$a.">", "</".$a.">", $str); } return $str; } echo allow_only('This is <b>bold</b> and <a href="http://www.#links">this</a> is <i>italic</i>.', array("b","a"));
который обрабатывает более сложные теги с определенными атрибутами, этим атрибутам могут отображаться только символы, перечисленные между []
. К сожалению "
должен быть разрешен внутри атрибутов или он не будет работать, и вместе с этим разрешены все другие сущности – однако только в атрибутах будут декодироваться.
Как было предложено гораздо лучше (более безопасный, более чистый) способ решения таких проблем, как использование библиотеки, например http://htmlpurifier.org/demo.php