Есть ли альтернатива PHP's strip_tags ()

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

Давайте забудем о названии и придем к тому, что я хочу спросить. Я хочу, чтобы функциональность удаляла только те теги, которые я упоминаю во втором параметре. то есть. Я хочу, чтобы следующее разделило теги <iframe><script><style><embed><object> и разрешить все остальные.

 my_strip_tags($data,'<iframe><script><style><embed><object>'); 

Это довольно противоположно тому, что strip_tags() .

Как это сделать?

Обновлено 2012-06-23; основной недостаток безопасности.

Вот класс из другого проекта, который должен делать то, что вы ищете:

 final class Filter { private function __construct() {} const SafeTags = 'a abbr acronym address b bdo big blockquote br caption center cite code col colgroup dd del dfn dir div dl dt em font h1 h2 h3 h4 h5 h6 hr i img ins kbd legend li ol p pre qs samp small span strike strong sub sup table tbody td tfoot th thead tr tt u ul var article aside figure footer header nav section rp rt ruby dialog hgroup mark time'; const SafeAttributes = 'href src title alt type rowspan colspan lang'; const URLAttributes = 'href src'; public static function HTML($html) { # Get array representations of the safe tags and attributes: $safeTags = explode(' ', self::SafeTags); $safeAttributes = explode(' ', self::SafeAttributes); $urlAttributes = explode(' ', self::URLAttributes); # Parse the HTML into a document object: $dom = new DOMDocument(); $dom->loadHTML('<div>' . $html . '</div>'); # Loop through all of the nodes: $stack = new SplStack(); $stack->push($dom->documentElement); while($stack->count() > 0) { # Get the next element for processing: $element = $stack->pop(); # Add all the element's child nodes to the stack: foreach($element->childNodes as $child) { if($child instanceof DOMElement) { $stack->push($child); } } # And now, we do the filtering: if(!in_array(strtolower($element->nodeName), $safeTags)) { # It's not a safe tag; unwrap it: while($element->hasChildNodes()) { $element->parentNode->insertBefore($element->firstChild, $element); } # Finally, delete the offending element: $element->parentNode->removeChild($element); } else { # The tag is safe; now filter its attributes: for($i = 0; $i < $element->attributes->length; $i++) { $attribute = $element->attributes->item($i); $name = strtolower($attribute->name); if(!in_array($name, $safeAttributes) || (in_array($name, $urlAttributes) && substr($attribute->value, 0, 7) !== 'http://')) { # Found an unsafe attribute; remove it: $element->removeAttribute($attribute->name); $i--; } } } } # Finally, return the safe HTML, minus the DOCTYPE, <html> and <body>: $html = $dom->saveHTML(); $start = strpos($html, '<div>'); $end = strrpos($html, '</div>'); return substr($html, $start + 5, $end - $start - 5); } } 

Это не должно происходить вообще.

strip_tags используется только при использовании без каких-либо параметров. В противном случае вы будете иметь XSS в любом разрешенном теге.

На самом деле, ваша озабоченность должна быть не только тегами, но и атрибутами . Итак, используйте вместо этого очиститель HTML.

Я обычно работаю с htmLawed lib, вы можете использовать его для фильтрации, защиты и дезинфекции HTML

http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/more.htm

Я думаю, что функция strip_tags () соответствует его имени. Все это вопрос перспективы. 🙂 Без второго параметра он разбивает все теги. Второй параметр предоставляет исключения для базовой функциональности.

Кажется, что вы хотите strip_some_tags() .

Как насчет того, чтобы просто делать это с регулярным выражением?

 function strip_some_tags($input, $taglist) { $output=$input; foreach ($taglist as $thistag) { if (preg_match('/^[az]+$/i', $thistag)) { $patterns=array( '/' . "<".$thistag."\/?>" . '/', '/' . "<\/".$thistag.">" . '/' ); } else if (preg_match('/^<[az]+>$/i', $thistag)) { $patterns=array( '/' . str_replace('>', "?>", $thistag) . '/', '/' . str_replace('<', "<\/?", $thistag) . '/' ); } else { $patterns=array(); } $output=preg_replace($patterns, "", $output); } return $output; } $to_strip=array( "iframe", "script", "style", "embed", "object" ); $sampletext="Testing. <object>Am I an object?</object>\n"; print strip_some_tags($sampletext, $to_strip); 

Возвращает:

 Testing. Am I an object? 

Конечно, это просто разметки тегов, а не вещи между ними. Это то, что вы хотите? Вы не указали в своем вопросе.