PHP中用于验证字符串是否为有效HTML的函数是哪个?

7

在PHP中,哪个函数可以验证字符串是否为HTML格式?

我的目标是从用户输入中获取数据,并检查其是否为HTML格式,而不仅仅是字符串。

以下是非HTML格式的示例:

sdkjshdk<div>jd</h3>ivdfadfsdf or sdkjshdkivdfadfsdf

HTML字符串的示例:

<div>sdfsdfsdf<label>dghdhdgh</label> fdsgfgdfgfd</div>

谢谢


这两个字符串都是 HTML 片段。前者显然无效,但两者都需要修改才能通过 W3C 验证器。我认为你需要更具体地说明你想要允许什么,以及你想要防止什么。 - Annika Backstrom
我的目标是从用户那里获取输入并检查输入是否为HTML而不仅仅是字符串。 - Ben
7个回答

11
也许您需要检查字符串是否格式正确。 我会使用这样的函数。
function check($string) {
  $start =strpos($string, '<');
  $end  =strrpos($string, '>',$start);

  $len=strlen($string);

  if ($end !== false) {
    $string = substr($string, $start);
  } else {
    $string = substr($string, $start, $len-$start);
  }
  libxml_use_internal_errors(true);
  libxml_clear_errors();
  $xml = simplexml_load_string($string);
  return count(libxml_get_errors())==0;
}

注意:HTML允许存在以下类似未平衡的字符串。它不是XML有效的块,但是它是合法的HTML块。

<ul><li>Hi<li> I'm another li</li></ul>

免责声明:我已经修改了代码(未经测试),以便检测字符串中的格式良好的HTML。

最后一点建议: 也许你应该使用strip_tags来控制用户输入(正如我在你的评论中看到的)。


1
这种方法在 方面失败了 - 没有明显的解决方法 :-( - ErichBSchulz
@ErichBSchulz 可能在测试之前只需要对 $string 进行 html_entity_decode($string)(快速而简单的解决方案,但应该足够了)。 - Eineki
html_entity_decode()不会做到这一点,例如因为它会将<更改为字面上的小于号,这至少会有错误的含义,并且很可能是非格式良好的。 - TextGeek
<br><p>FooBar 是有效的HTML(即使没有关闭 p 标签!),但是这种方法会报告错误。 - Stephan Vierkant

5
您可以使用DomDocument的方法loadHTML

3

如果没有单个根节点,simplexml_load_string将无法正常运行。

因此,如果您尝试使用以下HTML代码:

<p>A</p><p>B</p>它将是无效的。

这是我的函数:

function check($string){
    $start = strpos($string, '<');
    $end = strrpos($string, '>', $start);

    if ($end !== false) {
        $string = substr($string, $start);
    } else {
        $string = substr($string, $start, strlen($string) - $start);
    }

    // xml requires one root node
    $string = "<div>$string</div>";

    libxml_use_internal_errors(true);
    libxml_clear_errors();
    simplexml_load_string($string);

    return count(libxml_get_errors()) == 0;
}

2

您是指HTML还是XHTML?

HTML标准和解释非常宽松,因此您的第一个代码片段可能会起作用。它不会很美观,但您可能会得到一些结果。

XHTML要求相当严格,至少需要您的代码片段格式正确(所有开放的标签都被关闭;标签可以嵌套但不能重叠),如果存在未识别的元素或属性,则可能会抛出警告。

类似Tidy这样的工具 - http://php.net/manual/en/book.tidy.php - 可能是一个好的开始。加载您的代码片段后,您可以使用tidy_error_counttidy_get_error_buffer来查看是否符合您的需求。


我的目标是从用户那里获取输入并检查输入是否为HTML,而不仅仅是字符串。 - Ben
好的。两者都是HTML... HTML规范非常宽松,几乎没有什么影响。第二个是XHTML。如果这是你想要的,请尝试使用Tidy并看看你能做些什么。 - CaseySoftware
如果您处于可以接受第三方应用程序的情况下,tidy 可能是可接受的。但是,它对多个第三方产品的依赖性使其不适用于库的使用。 - Jay Bienvenu

2
你是否想要防止用户输入HTML标签而不是字符串?如果是的话,你只需要使用 strip_tags() 函数,它会从字符串中删除任何HTML标记。

2

您应该使用:

$html="<html><body><p>This is array.</p><br></body></html>";

libxml_use_internal_errors(true);
$dom = New DOMDocument();
$dom->loadHTML($html);
if (empty(libxml_get_errors())) {
  echo "This is a good HTML";
}else {
  echo "This not html";
}

Valentin Caamal,这段代码使用$html = $html.'<br>';会失败,因为逻辑上这不是正确的(x)HTML。然而,当使用$dom -> loadXML($html);$html = '<br /><p>k</p>';时,此函数也会失败(请注意loadXML)。 - Stackoverflow

0
如果您想使您的网站更加安全,那么您肯定需要使用像htmlpurifier、tidy等HTML净化器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接