试图确保html标签不会在php中保持打开状态

时间:2011-05-05 21:58:45

标签: php substr

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

<?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()来确保没有任何标签是打开的,但它不起作用。运行它给出:

  

标签未打开。李标签是开放的。 ul标签未打开。 ol标签未打开。

尽管他们都是开放的。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:0)

<a>“未打开”,因为stripos将返回第一次出现的位置,第一次出现位于索引0(计算结果为false)。

发现

<li>是开放的,因为它的索引不为零。但是你会截断搜索字符串,以便在零索引处找到下一个迭代<ul> ...

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

答案 1 :(得分:0)

您的逻辑似乎存在缺陷:strripos如果找不到指针则会返回false,因此如果数字大于{{1},您正在测试内部if语句中}。

对于外部false语句,您需要测试false:

if

你的内心if (stripos($text, $opentag) !== false) { // found at position 0 or more... 应该是这样的:

if

答案 2 :(得分:0)

以下是使用正则表达式的示例:

  $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, ";
    }
}

答案 3 :(得分:0)

解析HTML并非易事,并且有一些好的库可以为您完成这项工作。自PHP 5起,Tidy库已可用,可用于解析和整理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)。