代码之家  ›  专栏  ›  技术社区  ›  Tyler Carter

基于PHP的HTML验证器

  •  4
  • Tyler Carter  · 技术社区  · 16 年前

    我有一个字符串中的HTML:

    $html = "<html><head>.....</body></html>";
    

    我见过:
    http://www.bermi.org/xhtml_validator
    - http://twineproject.sourceforge.net/doc/phphtml.html

    这样做的背景是,我想在每个页面上运行一个函数/类,检查文件自上次访问日期以来是否被修改过(或类似的东西),如果没有,运行验证器,这样我在编码时就会立即收到无效HTML的通知。

    4 回复  |  直到 16 年前
        1
  •  6
  •   Robert Elwell    16 年前

    没有必要在这个问题上重新发明轮子。已经有了 PEAR library that interfaces with the W3C HTML Validator API 他们愿意为你做这项工作,为什么不让他们做呢? :)

        2
  •  2
  •   Byron Whitlock    16 年前

    虽然它不是严格意义上的PHP(它是一个可执行文件),但我真正喜欢的是w3c的HTML整洁。它将显示HTML的错误,如果你想修复它,它还会美化HTML,这样它就不会看起来一团糟。从命令行运行,易于集成到php中。

    过来看。 http://www.w3.org/People/Raggett/tidy/

        3
  •  0
  •   Pons    16 年前

    如果你不能使用Tidy(有时托管服务不会激活这个php模块),你可以使用这个php类: http://www.barattalo.it/html-fixer/

        4
  •  -2
  •   Nikos M.    4 年前

    我有一个案例,我需要检查部分html代码是否存在不匹配和格式错误的标签(主要是,例如</br>,我的示例中的一个常见错误),各种重型验证器太多了,无法使用。因此,我最终在PHP中创建了自己的自定义验证例程,它粘贴在下面(您可能需要使用 mb_substr 如果您有不同语言的文本,则不进行基于索引的字符检索)( 笔记 它不解析 CDATA 或脚本/样式标签,但可以轻松扩展):

    function check_html( $html )
    {
        $stack = array();
        $autoclosed = array('br', 'hr', 'input', 'embed', 'img', 'meta', 'link', 'param', 'source', 'track', 'area', 'base', 'col', 'wbr');
        $l = strlen($html); $i = 0;
        $incomment = false; $intag = false; $instring = false;
        $closetag = false; $tag = '';
        while($i<$l)
        {
            while($i<$l && preg_match('#\\s#', $c=$html[$i])) $i++;
            if ( $i >= $l ) break;
            if ( $incomment && ('-->' === substr($html, $i, 3)) )
            {
                    // close comment
                    $incomment = false;
                    $i += 3;
                    continue;
            }
            $c = $html[$i++];
            if ( '<' === $c )
            {
                if ( $incomment ) continue;
                if ( $intag )  return false;
                if ( '!--' === substr($html, $i, 3) )
                {
                    // open comment
                    $incomment = true;
                    $i += 3;
                    continue;
                }
    
                // open tag
                $intag = true;
                if ( '/' === $html[$i] )
                {
                    $i++;
                    $closetag = true;
                }
                else
                {
                    $closetag = false;
                }
                $tag = '';
                while($i<$l && preg_match('#[a-z0-9\\-]#i', $c=$html[$i]) )
                {
                    $tag .= $c;
                    $i++;
                }
                if ( !strlen($tag) ) return false;
                $tag = strtolower($tag);
                if ( $i<$l && !preg_match('#[\\s/>]#', $html[$i]) ) return false;
                if ( $i<$l && $closetag && preg_match('#^\\s*/>#sim', substr($html, $i)) ) return false;
                if ( $closetag )
                {
                    if ( in_array($tag, $autoclosed) || (array_pop($stack) !== $tag) )
                        return false;
                }
                else if ( !in_array($tag, $autoclosed) )
                {
                    $stack[] = $tag;
                }
            }
            else if ( '>' ===$c )
            {
                if ( $incomment ) continue;
                
                // close tag
                if ( !$intag ) return false;
                $intag = false;
            }
        }
        return !$incomment && !$intag && empty($stack);
    }
    
    推荐文章