2009-04-20 14 views

Odpowiedz

14

Chociaż istnieją lepsze sposoby, można faktycznie pozbawić argumentów ze znacznikami html z wyrażeń regularnych:

<?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; 
} 
?> 

Powyższy prawdopodobnie mogłyby być napisane w mniej znaków, ale spełnia swoje zadanie (szybki i brudny) .

-1

Możesz również zajrzeć do oczyszczacza html. To prawda, że ​​jest dość rozdęty i może nie pasować do twoich potrzeb, jeśli tylko pokaże ten konkretny przykład, ale oferuje mniej lub bardziej "kuloodporne" oczyszczenie możliwego wrogiego html. Możesz także zezwolić lub zabronić pewnych atrybutów (jest to wysoce konfigurowalny).

http://htmlpurifier.org/

9

Strip atrybutów przy użyciu SimpleXML (standard w 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); 

?> 
+0

Działa to doskonale, ale tylko jeśli twój wejściowy html jest poprawnie utworzony xml. W przeciwnym razie przed analizą konieczne będzie wykonanie wstępnego czyszczenia wejściowego html. Może to być dość uciążliwe dla odkażenia, jeśli nie masz dość kontroli nad wejściem html pochodzenia. –

7

Oto jedna funkcja, która pozwoli Ci strip wszystkie atrybuty z wyjątkiem tych, chcesz:

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; 
} 

W przykładzie byłby:

echo stripAttributes('<p class="one" otherrandomattribute="two">'); 

lub jeśli np. Aby zachować atrybut „class”:

echo stripAttributes('<p class="one" otherrandomattribute="two">', array('class')); 

Albo

Zakładając, że aby wysłać wiadomość do skrzynki odbiorczej i składa się wiadomość z CKEditor, można przypisać funkcję w następujący sposób i echo go do Zmienna $ message przed wysłaniem. Zauważ, że funkcja o nazwie stripAttributes() usunie wszystkie niepotrzebne znaczniki html. Próbowałem i działa dobrze. widziałem tylko formatowanie dodane jak pogrubione e.t.c.

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

lub może echo $message; do podglądu ty.

5

Szczerze myślę, że jedynym rozsądnym sposobem, aby to zrobić, jest użycie białej listy atrybutów znacznika i z biblioteką HTML Purifier. Przykład skryptu tutaj:

<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> 

Daje to następujące czyste, standardach zgodnych fragment 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> 

w Twoim przypadku whitelist byłoby:

$config->set('HTML.Allowed', 'p'); 
Powiązane problemy