Как удалить атрибуты из тега html?

Как я могу использовать php для удаления всех/любых атрибутов из тега, например, тега абзаца?

<p class="one" otherrandomattribute="two"> до <p>

Ответы

Ответ 1

Несмотря на то, что есть более эффективные способы, вы можете фактически деактивировать аргументы из тегов html с регулярным выражением:

<?php
function stripArgumentFromTags( $htmlString ) {
    $regEx = '/([^<]*<\s*[a-z](?:[0-9]|[a-z]{0,9}))(?:(?:\s*[a-z\-]{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;
}
?>

Выше, вероятно, может быть написано меньше символов, но он выполняет эту работу (быстро и грязно).

Ответ 2

Использовать атрибуты 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);

?>

Ответ 3

Вот одна функция, которая позволит вам удалить все атрибуты, кроме тех, которые вы хотите:

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, которые не нужны. Я попробовал, и все работает нормально. Я видел только форматирование, которое я добавил как bold e.t.c.

$message = stripAttributes($_POST['message']);

или вы можете echo $message; для предварительного просмотра.

Ответ 4

HTML Purifier - один из лучших инструментов для дезинфекции HTML с PHP.

Ответ 5

Я честно считаю, что единственный разумный способ сделать это - использовать белый список тегов и атрибутов с библиотекой HTML Purifier. Пример script здесь:

<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://www.example.com/www.example.com/bla.gif" alt="bla.gif" /><a href="http://www.google.de">missing end tag
ende 
</a></b>

В вашем случае белый список будет:

$config->set('HTML.Allowed', 'p');

Ответ 6

Вы также можете посмотреть очиститель html. Правда, он довольно раздутый и может не соответствовать вашим потребностям, если он только рассматривает этот конкретный пример, но он предлагает более или менее "пуленепробиваемую" очистку возможного враждебного html. Также вы можете разрешить или запретить определенные атрибуты (он очень настраивается).

http://htmlpurifier.org/