PHP запрещает strip_tags удалять неработающие теги

У меня та же ситуация, что и у этого этого парня.

В основном strip_tags удаляет теги, включая неработающие теги (термин, используемый в документация). Есть ли другой способ сделать это, который не включает удаление < и любого текста после него, если это не тег HTML?

Я сейчас делаю это:

$description = "&lt;p&gt;I am currently &lt;30 years old.&lt;/p&gt;";
$body = strip_tags(html_entity_decode($description, ENT_QUOTES, "UTF-8"), "<strong><em><u>");
echo $body;

Но приведенный выше код сломает что-то вроде:

<p>I am currently <30 years old.</p>

В:

I am currently

eval.in

Вот eval.in, чтобы вы поняли, что я имею в виду.


person Patrick Gregorio    schedule 24.06.2016    source источник
comment
мусор на входе, мусор на выходе. сначала зафиксируйте < в &lgt;, прежде чем запускать его с помощью различных инструментов.   -  person Marc B    schedule 25.06.2016
comment
@MarcB Я думал об этом, но посмотри на мой пример. Если я это сделаю, то мой текст станет &lt;p&gt;I am currently &lt; 30 years old.&lt;/p&gt;, и в этом случае последующее выполнение strip_tags ничего не даст.   -  person Patrick Gregorio    schedule 25.06.2016
comment
только если кодировать ВСЕ. вы не можете ожидать, что инструмент будет достаточно умным, чтобы понять, что сломано, а что нет. Это зависит от вас, чтобы подать соответствующий ввод. Если вы не можете исправить ввод, вы не можете использовать стандартные инструменты. например используйте строковую операцию, чтобы сделать str_replace(' < ', ' &lt; ', $str), чтобы закодировать любую голую фигурную скобку.   -  person Marc B    schedule 25.06.2016
comment
Я попробовал ваше выше с $description = '‹p›Мне сейчас ‹ 30 лет.‹/p›'.. Он возвращается - мне сейчас ‹ 30 лет. Ваш код у меня работает нормально.   -  person DBA    schedule 25.06.2016
comment
@DBA и @MarcB Извините за мой пример. Это должно быть <30 (без пробела между ними). eval.in/595272   -  person Patrick Gregorio    schedule 25.06.2016
comment
Зачем ты вообще хочешь убрать теги? Просто избегайте их правильно.   -  person tkausl    schedule 25.06.2016


Ответы (2)


HTML-код, который у вас есть в качестве входных данных, недействителен. Так что это нужно исправить. Вы можете сначала заменить все незакрытые < на &lt;, а затем выполнить html_entity_decode после strip_tags:

$description = "<p>I am currently <30 years old.</p>";
$description = preg_replace("/<([^>]*(<|$))/", "&lt;$1", $description);
$body = html_entity_decode(strip_tags($description, "<strong><em><u>"),
                           ENT_NOQUOTES, "UTF-8");
echo $body;

См. на eval.in.

В качестве альтернативы вы можете использовать синтаксический анализатор DOM, который в некоторых случаях может дать лучшие результаты, но вам все равно нужно сначала применить исправление:

$description = "<p>I am currently <30 years old.</p>";
$description = preg_replace("/<([^>]*(<|$))/", "&lt;$1", $description);
$doc = new DOMDocument();
$doc->loadHTML($description);
$body = $doc->documentElement->textContent;
echo $body;

См. на eval.in.

person trincot    schedule 24.06.2016

Обычно при использовании операторов «меньше» и «больше» вы почти всегда будете использовать числа (особенно вероятно здесь, поскольку с тех пор вы сказали, что пробелы не используются). Предполагая, что это ваш случай, вы можете довольно легко использовать preg_match для регулярного выражения этого сценария, прежде чем запускать его через strip_tags:

$description = "<p>I am currently <30 years old.</p>";
$description = preg_replace("/<([0-9]+)/", "&lt;$1", $description);
$body = strip_tags($description, "<strong><em><u>");
echo $body;
person Ian    schedule 24.06.2016