php htmlentities标记异常只允许某些标记工作

php htmlentities标记异常只允许某些标记工作,php,html-entities,strip-tags,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>"; } while(

我可以不允许使用此代码的所有HTML标记正常工作:

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

但是如果我想允许一些标签例外呢

我想要的结果是禁用除



示例:(允许
和不允许

sometextsometext

预期结果:

sometext
sometext


查看图片:

这是您的结果:

   from_bold_text<div>from_div_text</div>
请注意在底部设置允许使用的标签:

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);
function strip\u html\u标记($text)
{
$text=preg\u replace(
排列(
//删除不可见内容
“@]*?>.@siu',//这是您的DISSALOW标签和内容
'@]*?>.'@siu',
'@]*?>.'@siu',
“@]*?*?*?@siu”,
“@]*?*?*?@siu”,
“@]*?*?*?@siu”,
“@]*?*?*?@siu”,
“@]*?*?*?@siu”,
“@]*?*?*?@siu”,
“@]*?*?*?@siu”,
//在块之前和之后添加换行符

“@这段代码完成了这项工作,使用
DOMDocument
解析HTML代码。它似乎比正则表达式更可靠(如果用户在禁止的标记中插入一个属性会发生什么情况?可能包含
?),尤其是在阅读之后;尽管它需要更多的工作,但不一定更快

<?

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

}

?>
loadHTML($text);
$doc->loadXML(“$text.\n”);
//找到尸体
$body=$doc->getElementsByTagName(“body”)->item(0);
//做事
$child=$body->firstChild;
while($child!=NULL){
$child=selective\u escape\u节点($child,$allowed\u标记);
}
//输出innerHTML。需要再次循环吗
$retval=“”;
$child=$body->firstChild;
while($child!=NULL){
$retval.=$doc->saveHTML($child);
$child=$child->nextSibling;
}
返回$retval;
}
/**对不在DOM树的$allowed_标记中的标记转义HTML。
*@返回要处理的下一个同级,如果我们到达最后一个子级,则返回NULL。
*
*该函数用两个文本节点替换了一个禁止的标记,这两个文本节点将
*旧节点的子节点。
*/
函数选择\转义\节点($node,$allowed\标记){
//预处理子对象
如果($node->hasChildNodes()){
$child=$node->firstChild;
while($child!=NULL){
$child=selective\u escape\u节点($child,$allowed\u标记);
}
}
//检查$node上是否还有其他操作
if($node->nodeType==XML\u元素\u节点){
如果(!in_数组($node->nodeName,$allowed_标记)){
//将子节点移动到$node之前
$firstChild=NULL;
而($node->hasChildNodes()){
$child=$node->firstChild;
如果($firstChild==NULL)$firstChild=$child;
$node->removeChild($child);
$node->parentNode->insertBefore($child,$node);
}
//现在$node没有子节点。
$outer_html=$node->ownerDocument->saveHTML($node);
//两种情况。以“/>”或“”结尾。
if(substr($outer_html,-2)==“/>”){
//剥去“/>”
$outer\u html=substr($outer\u html,0,strlen($outer\u html)-2);
}否则{
//找到结束标记
$close_tag=strpos($outer_html,“>”);
如果($close_tag===false){
//哦,出什么事了
返回NULL;
}否则{
//带“>”
$outer\u html=substr($outer\u html,0,$close\u标记);
}
}
//将textnode放在第一个子节点之前
$txt1=$node->ownerDocument->createTextNode($outer_html。“>”);
//另一个在$node之前
$txt2=$node->ownerDocument->createTextNode(“”);
//请注意,createTextNode会自动转义“”。
$node->parentNode->insertBefore($txt1,$firstChild);
$node->parentNode->insertBefore($txt2,$node);
//选择要处理的下一个节点
$next=$node->nextSibling;
//删除节点
$node->parentNode->removeChild($node);
返回$next;
}
}
//转到下一个兄弟姐妹
返回$node->nextSibling;
}
?>

在htmlentities/specialchars\u解码调用之前运行strip\u标记时会发生什么情况?strip\u标记根本没有任何效果。我还没有弄清楚如何正确使用它。请为每个步骤添加一些示例输出。如果您使用strip\u标记作为第一步,它应该按照广告的方式工作。请尝试$text=htmlentities($text,ENT_引号,“UTF-8”,真);首先。这将确保只在开始进行基本调试时对html进行编码:在每个阶段之前/之后输出$text,以便查看发生的情况。我需要修改此设置,以禁止聊天中使用任何html标记,只允许使用粗体标记…明白我的意思吗?您的代码很好,但如果用户tes,这将完全显示在聊天中!无需删除标记,只需显示原始代码!查看图片,您可以发布一个更新工作示例吗?这将非常好。提前感谢。嘿,您的结果完成了,您需要知道何时要过滤字符串,将其放在正则表达式中,并保存内容,然后返回。之后trip标记您想要的任何内容。请注意
\$0
将作为过滤字符串的返回值,因此我在
preg_replace()
函数的第二个方法中从数组()的开头添加了。返回的语句如下。我按原样粘贴了代码,但出现了以下错误:“解析错误:语法错误,意外”['in/path.php第3行“@user3746998您就是我们
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
<?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>';
echo strip_tags_content($text, '<b>', FALSE);
<b>sometext_from_bold</b>
<?

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

}

?>