Есть ли способ определить, имеет ли строка допустимый синтаксис HTML в PHP или symfony?

#php #html #symfony

#php #HTML #symfony

Вопрос:

просто у меня есть строка, подобная:

 <h2 Article name</h2>This is an idea.<ul style="color:green;"><li>option 1</li><li>option 2</li><li>option 1<li></ul>
 

Как вы можете видеть, что это недопустимо, как symfony или просто PHP могут обнаружить это и вернуть, где ошибка?

Я нашел следующий код:

 private function validateHTML($string)
{
    preg_match_all('#<(?!meta|img|br|hr|inputb)b([a-z] )(?: .*)?>#iU', $string, $result);
    $openedTags = $result[1];
    preg_match_all('#</([a-z] )>#iU', $string, $result);
    $closedTags = $result[1];
    $len_opened = count($openedTags);

    return (count($closedTags) == $len_opened) ? $string : false;
}
 

но иногда это работает хорошо, но не для примера, который я заметил вверху, например.

Я использую symfony 4.2

Ответ №1:

Я думаю, что лучший способ — отобразить его, а затем проверить его на ошибку,
протестировав этот код:

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

вывод

 This is a good HTML
 

Другой способ

вы также можете использовать simplexml_load_string для проверки своего html, как в этом примере:

 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);
    }

    $string = "<div>$string</div>";

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

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

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

if (check($html)) {
  echo "This is a good HTML";
} else {
  echo "This not html";
}
 

Но у этого способа есть одна проблема, и, например, если у вас есть <br> тег в вашем коде, он возвращает false, поэтому я рекомендую использовать первый способ, который лучше

Комментарии:

1. Спасибо за ответ, у меня была только проблема, что у меня не всегда есть основные теги html (HTML, Head, Body … и т.д. …), Поэтому второй ответ был именно тем, что я хотел 🙂

Ответ №2:

DOMDocument PHP в сочетании с libxml может помочь с подобными вещами. Простая функция, которая возвращает true или false в зависимости от того libxml , генерирует ошибку или нет

 <?php
    #The string to test
    $str='<h2 Article name</h2>This is an idea.<ul style="color:green;"><li>option 1</li><li>option 2</li><li>option 1<li></ul>';

    
    function isValidHTML($str=false){
        $base='
        <!DOCTYPE html>
        <html>
            <head>
                <title></title>
            </head>
            <body>%s</body>
        </html>';
        $html=sprintf( $base, $str );
        
        libxml_use_internal_errors( true );
        $dom=new DOMDocument;
            
        $dom->validateOnParse=false;
        $dom->recover=true;
        $dom->strictErrorChecking=false;
        $dom->loadHTML( $html );
        
        $errors=libxml_get_errors();
        libxml_clear_errors();
        
        return empty( $errors );
    }
    
    

    $valid=isValidHTML( $str );
    echo $valid ? 'Valid' : 'Bogus';
?>