为什么即使在以下场景中使用strip_tags函数后也不会删除HTML标记?

时间:2015-04-24 05:49:16

标签: php html arrays associative-array strip-tags

我有一个名为$aMessages的数组。实际上它是一个非常庞大的阵列,但为了您的参考,我只在其下面打印了前三个元素:

Array
(
    [0] => Array
        (
            [message_id] => 240
            [thread_id] => 43
            [user_id] => 244
            [text] => test msg<div class="mail_attach_image"><a class="group1" href="http://52.1.47.143/file/attachment/2015/04/49c79e88b24a8fff8104909fce19aa3f.png" ><img src="http://52.1.47.143/file/attachment/2015/04/49c79e88b24a8fff8104909fce19aa3f.png"  /></a><br><a class="mail_attach_image_link_dwl"  href="http://52.1.47.143/feed/download/year_ 2015/month_04/file_49c79e88b24a8fff8104909fce19aa3f.png" >Download</a></div>
            [time_stamp] => 1429695832
            [total_attachment] => 0
            [is_mobile] => 0
            [has_forward] => 0
            [profile_page_id] => 0
            [user_server_id] => 0
            [user_name] => profile-244
            [full_name] => CampusKnot .
            [gender] => 1
            [user_image] => 2015/03/ae6f1665efc29eb3360d392bbcd183b7%s.jpg
            [is_invisible] => 0
            [user_group_id] => 7
            [language_id] => �
            [forwards] => Array
                (
                )

        )

    [1] => Array
        (
            [message_id] => 241
            [thread_id] => 43
            [user_id] => 901
            [text] => hi
            [time_stamp] => 1429695875
            [total_attachment] => 0
            [is_mobile] => 0
            [has_forward] => 0
            [profile_page_id] => 0
            [user_server_id] => 1
            [user_name] => profile-901
            [full_name] => Student Campusknot
            [gender] => 2
            [user_image] => 2014/11/b23e023750785c8b5e61ace4d6a202fa%s.png
            [is_invisible] => 0
            [user_group_id] => 6
            [language_id] => �
            [forwards] => Array
                (
                )

        )

    [2] => Array
        (
            [message_id] => 243
            [thread_id] => 43
            [user_id] => 244
            [text] => textmessage
            [time_stamp] => 1429710052
            [total_attachment] => 0
            [is_mobile] => 0
            [has_forward] => 0
            [profile_page_id] => 0
            [user_server_id] => 0
            [user_name] => profile-244
            [full_name] => CampusKnot .
            [gender] => 1
            [user_image] => 2015/03/ae6f1665efc29eb3360d392bbcd183b7%s.jpg
            [is_invisible] => 0
            [user_group_id] => 7
            [language_id] => �
            [forwards] => Array
                (
                )

        )
)

如果您仔细观察第一个元素[&#39; text&#39;]键,则会出现一些HTML代码。我想删除此HTML代码并保留文本值(在这种情况下,值&#39; test msg&#39;只应该保留在那里,所有其他HTML代码都应该删除)。

基本上我想要的是检查每个元素的[&#39; text&#39;]键值是否存在HTML代码。

如果存在HTML代码,则应将其删除,并且仅保留纯文本。

为此,我尝试了以下代码,但没有改变:

foreach($aMessages as $key => $value) {
  $value['text'] = strip_tags($value['text']);
}

有人可以在这方面帮助我吗?

提前致谢。

4 个答案:

答案 0 :(得分:1)

foreach创建数组的副本。您的$value将不会在原始数组中更改。更改原始数组中的值或通过引用分配$value

引用http://php.net/manual/en/control-structures.foreach.php

  

为了能够使用$value&之前的循环中直接修改数组元素。在这种情况下,该值将通过引用分配。

另见How does PHP 'foreach' actually work?

关于你的评论

  

我的问题是HTML锚标记之间的字符串不会被忽略。

是的,strip_tags将按照名称所暗示的那样行事。它剥离标签。但不是他们的内容。

Either use ext/DOM to only fetch the first text nodesimply cut off everything after the first <。第一种方法需要更多代码。后者不太可靠,因为文本可能包含不是标签的常规小于

可靠性和代码量之间的良好平衡将是compare the original string against the stripped string,然后只将子字符串从开头返回到第一个不同的字符,例如

$text = substr($string, 0, strspn($string ^ strip_tags($string), "\0"));

请注意,这些方法都没有考虑到外部标签可能存在文字,例如: textMsg<b>foo</b>bar<i>baz</i>end只会产生“textMsg”。如果你想“textMsg bar end”使用这样的DOM:

$string = 'textMsg<b>foo</b>bar<i>baz</i>end';

libxml_use_internal_errors(true);
$dom = new DOMDocument;
$dom->loadHTML('<div id="root">' . $string . '</div>');
$xpath = new DOMXPath($dom);
$combinedDirectTextNodes = [];
foreach ($xpath->evaluate('id("root")/text()') as $text) {
    $combinedDirectTextNodes[] = $text->nodeValue;
};
libxml_use_internal_errors(false);

echo implode(' ', $combinedDirectTextNodes); // textMsg bar end

答案 1 :(得分:0)

尝试:

foreach($aMessages as $key => $value) {
    $aMessages[$key]['text'] = strip_tags($value['text']);
}

答案 2 :(得分:0)

  1. 您应该在foreach循环中修改原始数组而不是克隆。
  2. 您不能使用strip_tags()删除标记和标记内的内容。 strip_tags()只删除标记。
  3. 试试这个:

    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; 
    }
    
    foreach($aMessages as $key => $value) {
      $value['text'] = strip_tags_content($value['text']);
    }
    

答案 3 :(得分:-1)

如果我没有错,那么这对您有用,如果您的问题只是test msg仅使用strip_tags它会删除所有标记,但其余数据会在那里

foreach($aMessages as $key => &$value){
    $aMessages[$key]['text'] = substr($value['text'],0,strpos($value['text'],'<'));
}
print_r($aMessages); //Array ( [0] => Array ( [message_id] => 240 [thread_id] => 43 [user_id] => 244 [text] => test msg [time_stamp] => 1429695832 [total_attachment] => 0 [is_mobile] => 0 ) [1] => Array ( [message_id] => 241 [thread_id] => 43 [user_id] => 901 [text] => [time_stamp] => 1429695875 [total_attachment] => 0 [is_mobile] => 0 ) [2] => Array ( [message_id] => 243 [thread_id] => 43 [user_id] => 244 [text] => [time_stamp] => 1429710052 [total_attachment] => 0 [is_mobile] => 0 ) )