php htmlentities标签异常只留下确定的工作

时间:2014-07-04 16:33:21

标签: php html-entities strip-tags

我没有问题,禁止所有HTML代码使用此代码正常工作:

while($row = $result->fetch_array()){
        echo "<span class='names'>".htmlentities($row['username'])."</span>:<span class='messages'>".htmlentities($row['msg'])."</span><br>";  
}


但是,如果我想允许某些标签例外呢?

我想要的结果是禁用除<p><b><h2>

之外的任何标记



示例:(允许<b>并禁止<div>

<b>sometext</b><div>sometext</div>


预期成果:

sometext <div>sometext</div>

查看图片:enter image description here

2 个答案:

答案 0 :(得分:0)

这是您的结果:

请注意在底部设置允许的标签:

function strip_html_tags( $text )
{
    $text = preg_replace(
        array(
          // Remove invisible content
            '@<b[^>]*?>.*?</b>@siu',   // HERE IS YOUR DISSALOW TAG WITH CONTENT
            '@<head[^>]*?>.*?</head>@siu',
            '@<style[^>]*?>.*?</style>@siu',
            '@<script[^>]*?.*?</script>@siu',
            '@<object[^>]*?.*?</object>@siu',
            '@<embed[^>]*?.*?</embed>@siu',
            '@<applet[^>]*?.*?</applet>@siu',
            '@<noframes[^>]*?.*?</noframes>@siu',
            '@<noscript[^>]*?.*?</noscript>@siu',
            '@<noembed[^>]*?.*?</noembed>@siu',
          // Add line breaks before and after blocks
            '@</?((address)|(blockquote)|(center)|(del))@iu',
            '@</?((h[1-9])|(ins)|(isindex)|(p)|(pre))@iu',
            '@</?((dir)|(dl)|(dt)|(dd)|(li)|(menu)|(ol)|(ul))@iu',
            '@</?((table)|(th)|(td)|(caption))@iu',
            '@</?((form)|(button)|(fieldset)|(legend)|(input))@iu',
            '@</?((label)|(select)|(optgroup)|(option)|(textarea))@iu',
            '@</?((frameset)|(frame)|(iframe))@iu',
        ),
        array(
            "\$0", // RETURNED STATEMENT
             ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
            "\$0", "\$0", "\$0", "\$0", "\$0", "\$0",
            "\$0", "\$0",
        ),
        $text );
    $to_strip =  strip_tags( $text, '<b>' );            // STRIP YOUR BOLD TAGS
    // add here to another + add content on above '@<b[^>]*?>.*?</b>@siu', and returns "\$0" on arrays
    return $to_strip;
}

      $e = '<b>from_bold_text</b><div>from_div_text</div>';

      echo strip_html_tags($e);

<强>结果:

   from_bold_text<div>from_div_text</div>

<击>

<击>
shell:~$ php ar.php 
<b>sometext</b>sometext

shell:~$ cat ar.php 
<?php

$t ="<b>sometext</b><div>sometext</div>";

$text = htmlentities($t, ENT_QUOTES, "UTF-8");
$text = htmlspecialchars_decode($text);
$text = strip_tags($text, "<p><b><h2>");

echo $text;

shell:~$ php ar.php 
<b>sometext</b>sometext

注意:strip_tags不会删除其中的值,只会删除标记。

$ text =' sometext sometext'; $ text2 = strip_tags($ text,''); 后续代码var_dump($文本2); //它将显示允许的标签和值。

要删除其中的值,请使用带有CONTENT ON MANUAL的正则表达式或其他函数:

<?php
function strip_tags_content($text, $tags = '', $invert = FALSE) {

  preg_match_all('/<(.+?)[\s]*\/?[\s]*>/si', trim($tags), $tags);
  $tags = array_unique($tags[1]);

  if(is_array($tags) AND count($tags) > 0) {
    if($invert == FALSE) {
      return preg_replace('@<(?!(?:'. implode('|', $tags) .')\b)(\w+)\b.*?>.*?</\1>@si', '', $text);
    }
    else {
      return preg_replace('@<('. implode('|', $tags) .')\b.*?>.*?</\1>@si', '', $text);
    }
  }
  elseif($invert == FALSE) {
    return preg_replace('@<(\w+)\b.*?>.*?</\1>@si', '', $text);
  }
  return $text;
}
?>

Sample text:
$text = '<b>sample</b> text with <div>tags</div>';

Result for strip_tags($text):
sample text with tags

Result for strip_tags_content($text):
text with

Result for strip_tags_content($text, '<b>'):
<b>sample</b> text with

Result for strip_tags_content($text, '<b>', TRUE);
text with <div>tags</div> 

您的期望:

$text = '<b>sometext_from_bold</b><div>sometext_from_div</div>';

//这里是函数函数strip_tags_content($ text,$ tags ='',$ invert = FALSE){ ....}

//您的结果

echo strip_tags_content($text, '<b>', FALSE);

结果:

<b>sometext_from_bold</b>

<击>

答案 1 :(得分:0)

此代码完成工作,使用DOMDocument解析HTML代码。它似乎比正则表达式更可靠(如果用户在禁止标签中插入属性会发生什么?可能包含<>?),特别是在阅读this question之后;它需要更多的工作,而且不一定更快。

<?

$allowed = ['strong'];  // your allowed tags
$text = "<div>\n" .
        "    <div style=\"color: #F00;\">\n" .
        "       Your <strong>User Text</strong> with DIVs.\n".
        "   </div>\n" .
        "   more <strong>text</strong>\n" .
        "</div>\n";

echo selective_escape($text, $allowed);
/* outputs:

&lt;div&gt;
    &lt;div style="color: #F00;"&gt;
       Your <strong>User Text</strong> with DIVs.
   &lt;/div&gt;
   more <strong>text</strong>
&lt;/div&gt;

*/





/** Escapes HTML entities everywhere but in the allowed tags.
 */
function selective_escape($text, $allowed_tags) {

    $doc = new DOMDocument();

    /* DOMDocument normalizes the document structure when loading,
       adding a bunch of <p> around text where needed. We don't need
       this as we're working only on small pieces of HTML.
       So we pretend this is a piece of XML code.
       */
    // $doc->loadHTML($text);
    $doc->loadXML("<?xml version=\"1.0\"?><body>" . $text . "</body>\n");

    // find the body
    $body = $doc->getElementsByTagName("body")->item(0);

    // do stuff
    $child = $body->firstChild;
    while ($child != NULL) {
        $child = selective_escape_node($child, $allowed_tags);
    }

    // output the innerHTML. need to loop again
    $retval = "";

    $child = $body->firstChild;
    while ($child != NULL) {
        $retval .= $doc->saveHTML($child);
        $child = $child->nextSibling;
    }

    return $retval;
}






/** Escapes HTML for tags that are not in $allowed_tags for a DOM tree.
 *  @returns the next sibling to process, or NULL if we reached the last child.
 *
 *  The function replaced a forbidden tag with two text nodes wrapping the
 *  children of the old node.
 */
function selective_escape_node($node, $allowed_tags) {

    // preprocess children
    if ($node->hasChildNodes()) {
        $child = $node->firstChild;
        while ($child != NULL) {

            $child = selective_escape_node($child, $allowed_tags);

        }
    }

    // check if there is anything to do on $node as well
    if ($node->nodeType == XML_ELEMENT_NODE) {
        if (!in_array($node->nodeName, $allowed_tags)) {

            // move children right before $node
            $firstChild = NULL;
            while ($node->hasChildNodes()) {
                $child = $node->firstChild;

                if ($firstChild == NULL) $firstChild = $child;
                $node->removeChild($child);

                $node->parentNode->insertBefore($child, $node);
            }

            // now $node has no children.
            $outer_html = $node->ownerDocument->saveHTML($node);

            // two cases. either ends in "/>", or in "</TAGNAME>".
            if (substr($outer_html, -2) === "/>") {

                // strip off "/>"
                $outer_html = substr($outer_html, 0, strlen($outer_html) - 2);

            } else {

                // find the closing tag
                $close_tag = strpos($outer_html, "></" . $node->nodeName . ">");

                if ($close_tag === false) {

                    // uh-oh. something wrong
                    return NULL;

                } else {

                    // strip "></TAGNAME>"
                    $outer_html = substr($outer_html, 0, $close_tag);

                }

            }

            // put a textnode before the first child
            $txt1 = $node->ownerDocument->createTextNode($outer_html . ">");
            // and another before $node
            $txt2 = $node->ownerDocument->createTextNode("</" . $node->nodeName . ">");

            // note that createTextNode automatically escapes "<>".
            $node->parentNode->insertBefore($txt1, $firstChild);
            $node->parentNode->insertBefore($txt2, $node);

            // pick the next node to process
            $next = $node->nextSibling;
            // remove node
            $node->parentNode->removeChild($node);

            return $next;
        }
    }

    // go to next sibling
    return $node->nextSibling;

}

?>