[PHP]tidy_config_count関数でTidyの設定エラー件数を取得する方法を解説

PHP

PHPのTidy拡張でHTMLを処理する際、設定オプションを誤って指定してしまうことがあります。tidy_config_count() は、tidy_parse_string() などに渡した設定オプションの中に不正なオプションや無効な値がいくつあったかを整数で返す関数です。

地味な存在ですが、Tidy の設定ミスを検出するデバッグ・品質保証の場面で役立ちます。この記事では基本仕様から実践的な活用パターンまで解説します。

関数概要

項目内容
関数名tidy_config_count()
読み方タイディ・コンフィグ・カウント
分類Tidy関数
対応バージョンPHP 5以降(Tidy拡張が有効な場合)
引数tidyオブジェクト
戻り値int(設定エラーの件数)
必要な拡張tidy(多くの環境で標準バンドル)
OOPスタイル$tidy->getOptDoc() ではなく tidy_config_count($tidy) のみ(OOPメソッドなし)

構文

tidy_config_count(tidy $tidy): int

tidy オブジェクトを1つ受け取り、そのオブジェクトの生成時(parse 時)に渡した設定オプションのうち、認識できなかった・無効だったオプションの件数を返します。

注意:tidy_config_count() には OOPスタイルの対応メソッドが存在しませんtidy_error_count()getErrorCount()tidy_access_count()getAccessCount() のような対応がなく、常に手続き型で呼び出す必要があります。

「設定エラー」とは何か

tidy_parse_string($html, $config, 'UTF8')
                           ↑
                      この配列の中に…

  'output-xhtml'  => true   → 有効なオプション(カウントされない)
  'typo-mistake'  => true   → 存在しないオプション名(カウントされる)
  'wrap'          => -1     → 無効な値(カウントされる)

Tidy が認識できないオプション名や、型・値が不正なオプションが「設定エラー」としてカウントされます。正常なオプションはカウントされません。

基本的な使い方

<?php
// 存在しないオプション名を含む設定
$config = [
    'output-xhtml'   => true,      // 有効
    'typo-option'    => true,      // 無効(存在しないオプション名)
    'char-encoding'  => 'utf8',    // 有効
    'unknown-key'    => 'value',   // 無効(存在しないオプション名)
];

$tidy = tidy_parse_string('<p>テスト</p>', $config, 'UTF8');
tidy_clean_repair($tidy);

$configErrors = tidy_config_count($tidy);
echo "設定エラー: {$configErrors} 件" . PHP_EOL;

実行結果:

設定エラー: 2 件

実践的なコード例

例1:設定エラーを検出して警告を出す基本クラス

<?php
class TidyConfigValidator
{
    public function validate(string $html, array $config): array
    {
        $tidy = tidy_parse_string($html, $config, 'UTF8');
        tidy_clean_repair($tidy);

        $configErrors = tidy_config_count($tidy);

        if ($configErrors > 0) {
            trigger_error(
                "Tidyの設定に {$configErrors} 件の無効なオプションが含まれています。",
                E_USER_WARNING
            );
        }

        return [
            'config_errors'          => $configErrors,
            'html_errors'            => tidy_error_count($tidy),
            'html_warnings'          => tidy_warning_count($tidy),
            'accessibility_warnings' => tidy_access_count($tidy),
            'config_is_valid'        => $configErrors === 0,
        ];
    }
}

$validator = new TidyConfigValidator();

$result = $validator->validate('<p>サンプル<b>テキスト</b></p>', [
    'output-xhtml'  => true,
    'wrap'          => 80,
    'bad-option'    => 'oops',  // 無効なオプション
]);

print_r($result);

実行結果:

Warning: Tidyの設定に 1 件の無効なオプションが含まれています。
Array
(
    [config_errors] => 1
    [html_errors] => 0
    [html_warnings] => 0
    [accessibility_warnings] => 0
    [config_is_valid] =>
)

例2:有効な設定と無効な設定を比較する

<?php
class TidyConfigComparator
{
    private string $sampleHtml = '<html><body><p>テスト</p></body></html>';

    public function compare(array $validConfig, array $invalidConfig): void
    {
        $tidyValid = tidy_parse_string($this->sampleHtml, $validConfig, 'UTF8');
        tidy_clean_repair($tidyValid);

        $tidyInvalid = tidy_parse_string($this->sampleHtml, $invalidConfig, 'UTF8');
        tidy_clean_repair($tidyInvalid);

        printf("有効な設定の設定エラー数  : %d 件\n", tidy_config_count($tidyValid));
        printf("無効な設定の設定エラー数  : %d 件\n", tidy_config_count($tidyInvalid));
    }
}

$comparator = new TidyConfigComparator();
$comparator->compare(
    ['output-xhtml' => true, 'wrap' => 0, 'char-encoding' => 'utf8'],
    ['output-xhtml' => true, 'typo' => true, 'does-not-exist' => 'yes']
);

実行結果:

有効な設定の設定エラー数  : 0 件
無効な設定の設定エラー数  : 2 件

例3:設定ファイルから読み込んだオプションを検証する

<?php
class TidyConfigFileValidator
{
    public function validateFromFile(string $configFilePath, string $sampleHtml = '<p>test</p>'): bool
    {
        if (!file_exists($configFilePath)) {
            throw new RuntimeException("設定ファイルが見つかりません: {$configFilePath}");
        }

        $config = json_decode(file_get_contents($configFilePath), true);

        if (!is_array($config)) {
            throw new RuntimeException("設定ファイルの形式が不正です(JSON配列が必要)。");
        }

        $tidy = tidy_parse_string($sampleHtml, $config, 'UTF8');
        tidy_clean_repair($tidy);

        $errors = tidy_config_count($tidy);

        if ($errors > 0) {
            printf(
                "警告: 設定ファイル '%s' に %d 件の無効なオプションが含まれています。\n",
                basename($configFilePath),
                $errors
            );
            return false;
        }

        echo "設定ファイルは有効です。" . PHP_EOL;
        return true;
    }
}

// tidy-config.json の内容例:
// {"output-xhtml": true, "wrap": 80, "bad-key": true}

$validator = new TidyConfigFileValidator();
// $validator->validateFromFile('/path/to/tidy-config.json');

設定を外部JSONファイルで管理している場合、デプロイ前の検証ステップとして tidy_config_count() を使うことでオプション名のタイポを早期に発見できます。

例4:全カウント系関数をまとめて取得するサマリークラス

<?php
class TidySummaryCollector
{
    public function collect(string $html, array $config = []): array
    {
        $defaultConfig = [
            'accessibility-check' => 1,
            'output-xhtml'        => true,
            'char-encoding'       => 'utf8',
        ];

        $mergedConfig = array_merge($defaultConfig, $config);

        $tidy = tidy_parse_string($html, $mergedConfig, 'UTF8');
        tidy_clean_repair($tidy);

        return [
            'config_errors'          => tidy_config_count($tidy),
            'html_errors'            => tidy_error_count($tidy),
            'html_warnings'          => tidy_warning_count($tidy),
            'accessibility_warnings' => tidy_access_count($tidy),
            'repaired_html'          => (string) $tidy,
        ];
    }

    public function printSummary(array $result): void
    {
        printf("設定エラー              : %d 件\n", $result['config_errors']);
        printf("HTMLエラー              : %d 件\n", $result['html_errors']);
        printf("HTML警告                : %d 件\n", $result['html_warnings']);
        printf("アクセシビリティ警告    : %d 件\n", $result['accessibility_warnings']);
        $isClean = $result['config_errors'] === 0
                && $result['html_errors'] === 0
                && $result['accessibility_warnings'] === 0;
        echo "総合判定: " . ($isClean ? '✓ 問題なし' : '✗ 要確認') . PHP_EOL;
    }
}

$collector = new TidySummaryCollector();

$html = '<html><body><img src="a.jpg"><p>テスト</p></body></html>';

// 有効な設定
$result = $collector->collect($html, ['wrap' => 0]);
$collector->printSummary($result);

echo PHP_EOL;

// 無効なオプションを混入
$result2 = $collector->collect($html, ['wrap' => 0, 'invalid-opt' => true]);
$collector->printSummary($result2);

実行結果:

設定エラー              : 0 件
HTMLエラー              : 0 件
HTML警告                : 0 件
アクセシビリティ警告    : 1 件
総合判定: ✗ 要確認

設定エラー              : 1 件
HTMLエラー              : 0 件
HTML警告                : 0 件
アクセシビリティ警告    : 1 件
総合判定: ✗ 要確認

tidy_config_count() を他のカウント系関数と並べて一括取得することで、設定・HTML品質・アクセシビリティの3軸を同時に確認できるサマリーを作れます。

例5:環境ごとの設定切り替えと検証

<?php
class EnvironmentAwareTidyFactory
{
    private array $configs = [
        'production' => [
            'output-xhtml'   => true,
            'wrap'           => 0,
            'char-encoding'  => 'utf8',
            'show-body-only' => true,
        ],
        'development' => [
            'output-xhtml'        => true,
            'wrap'                => 80,
            'indent'              => true,
            'char-encoding'       => 'utf8',
            'show-body-only'      => true,
            'accessibility-check' => 1,
        ],
    ];

    public function parse(string $html, string $env = 'production'): tidy
    {
        $config = $this->configs[$env] ?? $this->configs['production'];

        $tidy = tidy_parse_string($html, $config, 'UTF8');
        tidy_clean_repair($tidy);

        $configErrors = tidy_config_count($tidy);
        if ($configErrors > 0) {
            trigger_error(
                "環境 '{$env}' のTidy設定に {$configErrors} 件の不正なオプションがあります。",
                E_USER_WARNING
            );
        }

        return $tidy;
    }
}

$factory = new EnvironmentAwareTidyFactory();
$tidy = $factory->parse('<p>本番コンテンツ</p>', 'production');
echo tidy_config_count($tidy) === 0 ? "設定OK" : "設定に問題あり";
echo PHP_EOL;

実行結果:

設定OK

例6:設定エラーをCIで検出して終了コードに反映する

<?php
class TidyConfigCiChecker
{
    public function run(array $configsToTest): int
    {
        $totalErrors = 0;

        foreach ($configsToTest as $label => $config) {
            $tidy = tidy_parse_string('<p>test</p>', $config, 'UTF8');
            tidy_clean_repair($tidy);
            $errors = tidy_config_count($tidy);

            $icon = $errors === 0 ? '✓' : '✗';
            printf("[%s] %-20s 設定エラー: %d 件\n", $icon, $label, $errors);
            $totalErrors += $errors;
        }

        echo PHP_EOL . "合計設定エラー: {$totalErrors} 件" . PHP_EOL;
        return $totalErrors === 0 ? 0 : 1;
    }
}

$checker = new TidyConfigCiChecker();

$exitCode = $checker->run([
    'production config'  => ['output-xhtml' => true, 'wrap' => 0],
    'staging config'     => ['output-xhtml' => true, 'bad-key' => true],
    'development config' => ['output-xhtml' => true, 'indent' => true, 'wrap' => 80],
]);

exit($exitCode);

実行結果:

[✓] production config   設定エラー: 0 件
[✗] staging config      設定エラー: 1 件
[✓] development config  設定エラー: 0 件

合計設定エラー: 1 件

例7:設定エラーの有無に応じてフォールバック設定を使う

<?php
class RobustTidyParser
{
    private array $fallbackConfig = [
        'output-xhtml'   => true,
        'char-encoding'  => 'utf8',
        'show-body-only' => true,
        'wrap'           => 0,
    ];

    public function parse(string $html, array $preferredConfig): string
    {
        $tidy = tidy_parse_string($html, $preferredConfig, 'UTF8');
        tidy_clean_repair($tidy);

        if (tidy_config_count($tidy) > 0) {
            trigger_error(
                '指定された設定に無効なオプションが含まれているため、フォールバック設定を使用します。',
                E_USER_WARNING
            );
            $tidy = tidy_parse_string($html, $this->fallbackConfig, 'UTF8');
            tidy_clean_repair($tidy);
        }

        return (string) $tidy;
    }
}

$parser = new RobustTidyParser();

$html = '<p>テスト<b>太字</b></p>';

// 不正なオプションを含む設定
$output = $parser->parse($html, [
    'output-xhtml' => true,
    'invalid-opt'  => 'yes',
]);

echo $output;

実行結果:

Warning: 指定された設定に無効なオプションが含まれているため、フォールバック設定を使用します。
<!DOCTYPE html>
<html>
<head>...</head>
<body><p>テスト<b>太字</b></p></body>
</html>

関連関数との比較

関数OOPスタイル取得できる件数
tidy_config_count()なし設定オプションのエラー件数
tidy_error_count()getErrorCount()HTML構文エラーの件数
tidy_warning_count()getWarningCount()HTML警告の件数
tidy_access_count()getAccessCount()アクセシビリティ警告の件数

Tidy のカウント系4関数の中で、tidy_config_count() だけが唯一「HTMLの品質」ではなく「Tidy自身の設定の正しさ」を返す関数です。また、4関数の中で唯一OOPスタイルのメソッドが存在しない点も特徴的です。

よくある落とし穴・注意点

  1. OOPスタイルのメソッドが存在しない tidy_error_count()tidy_access_count() にはそれぞれ getErrorCount()getAccessCount() という対応するOOPメソッドがありますが、tidy_config_count() にはOOPメソッドが存在しません。OOP中心のコードでも、この関数だけは手続き型で tidy_config_count($tidy) と呼び出す必要があります。
  2. tidy_clean_repair() の前後でも値は同じ 設定エラーの件数はHTML解析時点(parse 時)に確定するため、tidy_clean_repair() の呼び出し前後で値は変わりません。ただし、他のカウント系関数との一貫性のため、cleanRepair() 後に取得する習慣にしておくとコードが統一されます。
  3. 設定エラーが0でも設定の意図通りに動いているとは限らない オプション名が正しくても、値の型や範囲が期待と異なる場合があります。たとえば 'wrap' => true(整数が期待されるところにboolを渡す)が設定エラーとしてカウントされるかどうかはTidyのバージョンや実装次第です。設定の動作確認は、実際の出力HTMLを目視または tidy_error_count() と組み合わせて検証しましょう。
  4. Tidy拡張が無効な環境では使用できない 他のTidy関数と同様に、extension_loaded('tidy') で拡張の有効化を確認してから使用してください。

まとめ

ポイント内容
役割Tidyに渡した設定オプションの中の不正な件数を返す
引数tidyオブジェクト
戻り値int(設定エラーの件数)
OOPスタイル存在しない(手続き型のみ)
他のカウント系との違いHTML品質ではなくTidy設定の正しさを返す唯一の関数
よく組み合わせる関数tidy_parse_string(), tidy_clean_repair(), tidy_error_count()
主な用途設定ミスの検出、CIでのオプション名タイポ防止、フォールバック設計
注意点OOPメソッドなし、設定エラー0でも動作保証ではない

tidy_config_count() はTidyのカウント系関数の中でも最も使用頻度が低い部類ですが、設定を外部ファイルや動的生成で管理している場合のデバッグ、CIでの設定検証、フォールバック設計など、「設定の正しさを保証したい」場面で確実に役立つ関数です。OOPメソッドが存在しないという独特の制約だけ押さえておけば、迷わず使いこなせます。

タイトルとURLをコピーしました