【问题标题】:Trying to make sure html tags are not left open in php试图确保 html 标签没有在 php 中打开
【发布时间】:2011-08-19 18:17:02
【问题描述】:

我无法弄清楚为什么这段代码不起作用:

<?php
  $text = "<a><li><ul><ol>Hello";
  $tags = array('a', 'li', 'ul', 'ol');
  $tagcount = count($tags);
  $i = 0;

  while ($i < $tagcount) {
      $opentag = "<".$tags[$i];
      $closetag = "</".$tags[$i].">";

      if (stripos($text, $opentag)) {
          $lastopen = strripos($text, $opentag);
          $lastclose = strripos($text, $closetag);

          if ($lastopen > $lastclose) {
              $text = substr($text, 0, $lastopen);
              echo $tags[$i] . " tag was open. ";
          } else {
              echo $tags[$i] . " tag was closed. ";
      } else {
          echo $tags[$i] . " tag was not open. ";
      $i++;
  }
?>

它应该至少表明 $tags 数组中的所有标签都是打开的。它旨在使用 substr() 来确保没有任何标签是打开的,但它不起作用。运行这个给出:

标签未打开。 li 标签已打开。 ul 标签未打开。 ol 标签未打开。

即使它们都是开放的。任何帮助将不胜感激。

【问题讨论】:

    标签: php substr


    【解决方案1】:

    看来你的逻辑是有缺陷的:strripos 返回 false 如果没有找到针所以在你的内部 if 语句中你正在测试一个数字是否大于 false

    对于您的外部if 语句,您需要测试是否为false:

    if (stripos($text, $opentag) !== false) {
      // found at position 0 or more...
    

    你内心的if应该是这样的:

        if (($lastclose !== false) && ($lastopen > $lastclose)) {
    

    【讨论】:

      【解决方案2】:

      &lt;a&gt; 是“未打开”,因为 stripos 将返回第一次出现的位置,并且第一次出现在索引 0 处(计算结果为 false)。

      &lt;li&gt; 被发现是打开的,因为它的索引不为零。但随后您截断搜索字符串,以便在零索引处找到下一次迭代 &lt;ul&gt;...

      将您的 if 更改为 stripos($text, $opentag) === false 并查看是否允许您找到 a 标记为打开状态。您必须弄清楚如何处理 substr(...),因为我认为您的业务逻辑很可能会决定这一点。

      【讨论】:

        【解决方案3】:

        这是一个使用正则表达式的示例:

          $text = "<a><li><ul><ol>Hello";
          $tags = array('a', 'li', 'ul', 'ol');
          $tagcount = count($tags);
          $i = 0;
          $matches = array();
          foreach ($tags as $tag)
          {
            $closed = preg_match_all("/<\/".$tag.">/i", $text, $matches);
            $open = preg_match_all("/<".$tag.">/i", $text, $matches);
        
            if ($open == 0)
            {
                echo $tag." was not opened, ";
            }
            else if ($open > $closed)
            {
                echo $tag." was left open, ";
            }
            else
            {
                echo $tag." was closed properly, ";
            }
        }
        

        【讨论】:

          【解决方案4】:

          解析 HTML 并非易事,并且有一些很好的库可以为您完成这项工作。 Tidy 库从 PHP 5 开始可用,可用于解析和整理 HTML 片段,或完成页面输出。有一个很好的article on devzone,它展示了如何使用它,包括如何将它与output buffering结合起来。

          关于您发布的代码,您不应该在这样的 if 语句中使用 strpos。引用 PHP 手册:

          Warning: This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE, such as 0 or "" . . . Use the === operator for testing the return value of this function.

          所以要测试在字符串中没有找到子字符串,请执行以下操作:

          if(strpos($haystack, $needle) === FALSE)
          

          并测试是否找到了子字符串

          if(strpos($haystack, $needle) !== FALSE)
          

          但我真的非常建议使用预先存在的库来进行 HTML 操作或验证,尤其是在它对安全性敏感的情况下(例如反 XSS)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-07-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-21
            • 2018-04-25
            相关资源
            最近更新 更多