LoginSignup
27
29

More than 5 years have passed since last update.

PHPで壊れたHTMLを整形する

Last updated at Posted at 2014-05-23

整形したいデータ

以下の壊れたHTMLが $html に代入されているとします。

テストデータ
<html>
<p>
<a href="http://google.com/?q=あいうえお">あいうえおで検索</a>
<br>
<img src="hoge.jpg" alt="<'あいうえお'>">
A & B ><
<p></p>

整形する方法

Tidy を使う

最も「イイカンジ」に整形してくれて尚且つ実行速度も速いものはこれだと思います。但し、環境によっては拡張インストールが必要です。

テストコード
echo tidy_repair_string($html, ['indent' => true], 'utf8');
出力結果

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
  <head>
    <title></title>
  </head>
  <body>
    <p>
      <a href=
      "http://google.com/?q=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A">
      あいうえおで検索</a><br>
      <img src="hoge.jpg" alt="&lt;'あいうえお'&gt;"> A &amp; B &gt;&lt;
    </p>
  </body>
</html>

何で indent-attributes 有効化してないのに href の後で改行されてるんですかねぇ(憤怒

HTML Purifier を使う

ホワイトリスト方針のため、XSS防止における信頼性は抜群です。但し、ライブラリの設置が必要です。

テストコード
使った事が無くて最適なオプションを設定できる自信がないので誰か編集リクエストお願いします
出力結果
使った事が無くて最適なオプションを設定できる自信がないので誰か編集リクエストお願いします

DOM を使う

インデントを整えられないなど動作にやや不十分な点がありますが、拡張インストールやライブラリ無しで使えるメリットは大きいでしょう。

関数定義
function dom_repair_string($html) {
    static $dom;
    static $conv;
    static $rev;
    if ($dom === null) {
        $dom = new DOMDocument;
        $conv = function ($html) {
            return mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');
        };
        $rev = function ($matches) {
            return mb_convert_encoding($matches[0], 'UTF-8', 'HTML-ENTITIES');
        };
    }
    @$dom->loadHTML($conv($html));
    return preg_replace_callback('/(?:&#\d++;)++/', $rev, $dom->saveHTML());
}
テストコード
echo dom_repair_string($html);
出力結果
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>
<a href="http://google.com/?q=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A">あいうえおで検索</a>
<br><img src="hoge.jpg" alt="&lt;'あいうえお'&gt;">
A &amp; B &gt;</p></body></html>
27
29
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
29