Пытаясь убедиться, что HTML-теги не остаются открытыми в php - PullRequest
2 голосов
/ 06 мая 2011

Я не могу понять, почему этот код не работает:

<?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 не был открыт.

, хотя все они открыты.Любая помощь будет принята с благодарностью.

Ответы [ 4 ]

0 голосов
/ 06 мая 2011

Разбор HTML не является тривиальным, и есть несколько хороших библиотек, которые сделают эту работу за вас. Библиотека Tidy была доступна начиная с PHP 5 и может использоваться для анализа и очистки фрагментов HTML или для полного вывода страницы. Есть хорошая статья о devzone , в которой показано, как ее использовать, в том числе как объединить ее с буферизацией вывода .

Что касается кода, который вы разместили, вы не должны использовать strpos в выражении if, подобном этому. Цитировать руководство по PHP:

Предупреждение. Эта функция может возвращать логическое значение FALSE, но также может возвращать и не булево значение, которое оценивается как FALSE, например 0 или "". , , Используйте оператор === для проверки возвращаемого значения этой функции.

Чтобы проверить, что подстрока не найдена в строке, выполните:

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

И чтобы проверить, что подстрока была найдена:

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

Но я бы действительно советовал использовать уже существующую библиотеку для манипулирования или проверки HTML, особенно если она чувствительна к безопасности (например, anti-XSS).

0 голосов
/ 06 мая 2011

Кажется, ваша логика ошибочна: strripos возвращает false, если игла не найдена, поэтому в вашем внутреннем утверждении if, которое вы проверяете, если число больше false.

Для вашего внешнего if утверждения вы должны проверить на ложность:

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

Ваш внутренний if должен выглядеть примерно так:

    if (($lastclose !== false) && ($lastopen > $lastclose)) {
0 голосов
/ 06 мая 2011

Вот пример, который работает с использованием регулярных выражений:

  $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, ";
    }
}
0 голосов
/ 06 мая 2011

<a> не «открыт», потому что стрипы вернут позицию первого вхождения, а первое вхождение будет с индексом 0 (который оценивается как ложный).

<li> открыт, потому что его индекс не равен нулю.Но затем вы обрезаете строку поиска, чтобы следующая итерация <ul> была найдена с нулевым индексом ...

Измените свой if на stripos($text, $opentag) === false и посмотрите, позволяет ли он найти тег a какбыть открытым.Вам придется выяснить, что делать с substr (...), так как я думаю, что ваша бизнес-логика, скорее всего, будет диктовать это.

...