заменить все, кроме определенных html-тегов, на htmlspecialchars () в PHP?

Я хотел бы обработать свой пользовательский ввод, чтобы разрешить только определенные теги 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 &lt;i&gt;italic&lt;/i&gt;. Moreover 2&lt;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("&lt;".$a."&gt;", "<".$a.">", $str); $str = str_replace("&lt;/".$a."&gt;", "</".$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('&quot;','"',$match[2]).">"; } function allow_only($str, $allowed){ $str = htmlspecialchars($str); foreach( $allowed as $a ){ $str = preg_replace_callback("/&lt;(".$a."){1}([\s\/\.\w=&;:#]*?)&gt;/", fix_attributes, $str); $str = str_replace("&lt;/".$a."&gt;", "</".$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")); 

который обрабатывает более сложные теги с определенными атрибутами, этим атрибутам могут отображаться только символы, перечисленные между [] . К сожалению &quot; должен быть разрешен внутри атрибутов или он не будет работать, и вместе с этим разрешены все другие сущности – однако только в атрибутах будут декодироваться.

Как было предложено гораздо лучше (более безопасный, более чистый) способ решения таких проблем, как использование библиотеки, например http://htmlpurifier.org/demo.php