Как я могу использовать php для удаления всех / любых атрибутов из тега, например, тега абзаца?
<p class="one" otherrandomattribute="two">
to <p>
Хотя есть более эффективные способы, вы могли бы фактически стянуть аргументы из тегов html с регулярным выражением:
<?php function stripArgumentFromTags( $htmlString ) { $regEx = '/([^<]*<\s*[az](?:[0-9]|[az]{0,9}))(?:(?:\s*[az\-]{2,14}\s*=\s*(?:"[^"]*"|\'[^\']*\'))*)(\s*\/?>[^<]*)/i'; // match any start tag $chunks = preg_split($regEx, $htmlString, -1, PREG_SPLIT_DELIM_CAPTURE); $chunkCount = count($chunks); $strippedString = ''; for ($n = 1; $n < $chunkCount; $n++) { $strippedString .= $chunks[$n]; } return $strippedString; } ?>
Выше, вероятно, может быть написано меньше символов, но он выполняет эту работу (быстро и грязно).
Атрибуты Strip с использованием SimpleXML (Standard в PHP5)
<?php // define allowable tags $allowable_tags = '<p><a><img><ul><ol><li><table><thead><tbody><tr><th><td>'; // define allowable attributes $allowable_atts = array('href','src','alt'); // strip collector $strip_arr = array(); // load XHTML with SimpleXML $data_sxml = simplexml_load_string('<root>'. $data_str .'</root>', 'SimpleXMLElement', LIBXML_NOERROR | LIBXML_NOXMLDECL); if ($data_sxml ) { // loop all elements with an attribute foreach ($data_sxml->xpath('descendant::*[@*]') as $tag) { // loop attributes foreach ($tag->attributes() as $name=>$value) { // check for allowable attributes if (!in_array($name, $allowable_atts)) { // set attribute value to empty string $tag->attributes()->$name = ''; // collect attribute patterns to be stripped $strip_arr[$name] = '/ '. $name .'=""/'; } } } } // strip unallowed attributes and root tag $data_str = strip_tags(preg_replace($strip_arr,array(''),$data_sxml->asXML()), $allowable_tags); ?>
Вот одна функция, которая позволит вам удалить все атрибуты, кроме тех, которые вы хотите:
function stripAttributes($s, $allowedattr = array()) { if (preg_match_all("/<[^>]*\\s([^>]*)\\/*>/msiU", $s, $res, PREG_SET_ORDER)) { foreach ($res as $r) { $tag = $r[0]; $attrs = array(); preg_match_all("/\\s.*=(['\"]).*\\1/msiU", " " . $r[1], $split, PREG_SET_ORDER); foreach ($split as $spl) { $attrs[] = $spl[0]; } $newattrs = array(); foreach ($attrs as $a) { $tmp = explode("=", $a); if (trim($a) != "" && (!isset($tmp[1]) || (trim($tmp[0]) != "" && !in_array(strtolower(trim($tmp[0])), $allowedattr)))) { } else { $newattrs[] = $a; } } $attrs = implode(" ", $newattrs); $rpl = str_replace($r[1], $attrs, $tag); $s = str_replace($tag, $rpl, $s); } } return $s; }
В качестве примера можно привести:
echo stripAttributes('<p class="one" otherrandomattribute="two">');
или если вы, например. хотите сохранить атрибут «class»:
echo stripAttributes('<p class="one" otherrandomattribute="two">', array('class'));
Или
Предполагая, что вы должны отправить сообщение в папку «Входящие», и вы создали свое сообщение с помощью CKEDITOR, вы можете назначить функцию следующим образом и повторить ее перед переменной $ message перед отправкой. Обратите внимание, что функция с именем stripAttributes () отключит все теги html, которые не нужны. Я попробовал, и все работает нормально. Я видел только форматирование, которое я добавил как жирный и т. д.
$message = stripAttributes($_POST['message']);
или вы можете echo $message;
для предварительного просмотра.
HTML Purifier – один из лучших инструментов для дезинфекции HTML с PHP.
Я честно считаю, что единственный разумный способ сделать это – использовать ярлык тега и атрибута с библиотекой очистителя HTML . Пример скрипта здесь:
<html><body> <?php require_once '../includes/htmlpurifier-4.5.0-lite/library/HTMLPurifier/Bootstrap.php'; spl_autoload_register(array('HTMLPurifier_Bootstrap', 'autoload')); $config = HTMLPurifier_Config::createDefault(); $config->set('HTML.Allowed', 'p,b,a[href],i,br,img[src]'); $config->set('URI.Base', 'http://www.example.com'); $config->set('URI.MakeAbsolute', true); $purifier = new HTMLPurifier($config); $dirty_html = " <a href=\"http://www.google.de\">broken a href link</a fnord <x>y</z> <b>c</p> <script>alert(\"foo!\");</script> <a href=\"javascript:alert(history.length)\">Anzahl besuchter Seiten</a> <img src=\"www.example.com/bla.gif\" /> <a href=\"http://www.google.de\">missing end tag ende "; $clean_html = $purifier->purify($dirty_html); print "<h1>dirty</h1>"; print "<pre>" . htmlentities($dirty_html) . "</pre>"; print "<h1>clean</h1>"; print "<pre>" . htmlentities($clean_html) . "</pre>"; ?> </body></html>
Это дает следующий чистый, соответствующий стандартам HTML фрагмент:
<a href="http://www.google.de">broken a href link</a>fnord y <b>c <a>Anzahl besuchter Seiten</a> <img src="http://img.ruphp.com/php/bla.gif" alt="bla.gif" /><a href="http://www.google.de">missing end tag ende </a></b>
В вашем случае белый список будет:
$config->set('HTML.Allowed', 'p');
Вы также можете посмотреть очиститель html. Правда, он довольно раздутый и может не соответствовать вашим потребностям, если он только рассматривает этот конкретный пример, но он предлагает более или менее «пуленепробиваемую» очистку возможного враждебного html. Также вы можете разрешить или запретить определенные атрибуты (он очень настраиваемый).