2011-05-05 79 views
2

開我想不通爲什麼這個代碼不工作:努力確保HTML標記沒有被留在PHP

<?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++; 
    } 
?> 

它應該做的是至少表明了$標籤陣列中的所有標籤是開放的。它的意思是使用substr()來確保沒有標籤是打開的,但它不起作用。運行此產生:

標記未打開。 li標籤已打開。 ul標籤未打開。 ol標籤未打開。

儘管它們都是開放的。任何幫助將不勝感激。

回答

0

<a>'未打開',因爲stripos將返回第一次出現的位置,並且第一次出現位於索引0(其計算結果爲false)。

<li>被發現是開放的,因爲它的索引不是零。但你截斷搜索字符串,以便下一次迭代<ul>在零指數發現...

改變,如果對你的stripos($text, $opentag) === false,看看是否有可以讓你找到a標記爲打開。你必須弄清楚如何處理substr(...),因爲我認爲你的業務邏輯很可能決定這一點。

0

看來你的邏輯是有缺陷的:strripos回報false如果沒有找到針頭所以在你的內心if聲明你正在測試如果一個數比false更大。

爲了您的外if語句,你需要測試假:

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

你內心if應該是這樣的:

if (($lastclose !== false) && ($lastopen > $lastclose)) { 
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, "; 
    } 
} 
0

解析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)。