[PHP]tidy_get_opt_doc完全解説|Tidyオプションのドキュメント文字列を取得してコード内自己文書化を実現する

PHP

1. 関数概要

tidy_get_opt_doc は、PHP の Tidy 拡張が持つ各種設定オプションの**説明文(ドキュメント文字列)**を取得する関数です。オプション名を文字列で渡すと、Tidy ライブラリが内部的に保持しているそのオプションの仕様説明を返します。設定値の意味をコード内で動的に確認したい場面や、管理ツール・設定 UI の構築時に活用できます。

項目内容
関数名tidy_get_opt_doc
所属拡張Tidy
戻り値の型string|false
手続き型 / OOP手続き型(OOP 版: $tidy->getOptDoc(string $optname)
PHP バージョンPHP 5 以降
公式ドキュメントhttps://www.php.net/manual/ja/tidy.getoptdoc.php

2. 構文

// 手続き型
tidy_get_opt_doc(tidy $tidy, string $optname): string|false

// オブジェクト指向型
$tidy->getOptDoc(string $optname): string|false

パラメータ

パラメータ説明
$tidytidytidy_parse_string() 等で生成した tidy オブジェクト
$optnamestringドキュメントを取得したい Tidy オプション名(例: "indent", "wrap", "output-xhtml" など)

戻り値

  • オプション名が有効な場合: そのオプションの説明文字列(string
  • オプション名が無効・存在しない場合: false

3. 動作概念図

┌──────────────────────────────────────────────────────────┐
│  呼び出し側                                               │
│  tidy_get_opt_doc($tidy, "indent")                        │
└─────────────────────┬────────────────────────────────────┘
                      │ オプション名を検索
                      ▼
┌──────────────────────────────────────────────────────────┐
│  Tidy 内部オプションテーブル                              │
│  ┌────────────────┬──────────────────────────────────┐   │
│  │ オプション名   │ 説明文字列                        │   │
│  ├────────────────┼──────────────────────────────────┤   │
│  │ indent         │ "indents each new tag for ..."    │   │
│  │ wrap           │ "sets the column at which ..."    │   │
│  │ output-xhtml   │ "produces XHTML-compliant ..."    │   │
│  │ ...            │ ...                               │   │
│  └────────────────┴──────────────────────────────────┘   │
└─────────────────────┬────────────────────────────────────┘
                      │
          ┌───────────┴───────────┐
          │ 存在する              │ 存在しない
          ▼                       ▼
     string(説明文)           false

4. 基本的な使い方

<?php
$html = '<!DOCTYPE html><html><head><title>Test</title></head><body><p>Hello</p></body></html>';
$tidy = tidy_parse_string($html, [], 'UTF8');

// "indent" オプションの説明文を取得
$doc = tidy_get_opt_doc($tidy, 'indent');

if ($doc !== false) {
    echo "indent オプションの説明:" . PHP_EOL;
    echo $doc . PHP_EOL;
} else {
    echo "指定したオプションは存在しません。" . PHP_EOL;
}

出力例:

indent オプションの説明:
indents each new tag for readability. default is auto.

5. 実践的なコード例

例1: オプション説明を取得して表示するクラス

<?php
class TidyOptionDocViewer
{
    private tidy $tidy;

    public function __construct(string $html = '<html><body></body></html>')
    {
        $this->tidy = tidy_parse_string($html, [], 'UTF8');
    }

    public function getDoc(string $optname): string
    {
        $doc = tidy_get_opt_doc($this->tidy, $optname);
        return $doc !== false
            ? $doc
            : "オプション「{$optname}」は存在しません。";
    }

    public function print(string $optname): void
    {
        echo "[{$optname}]" . PHP_EOL;
        echo $this->getDoc($optname) . PHP_EOL;
    }
}

$viewer = new TidyOptionDocViewer();
$viewer->print('indent');
$viewer->print('wrap');
$viewer->print('output-xhtml');

出力例:

[indent]
indents each new tag for readability. default is auto.

[wrap]

sets the column at which line wrapping occurs.

[output-xhtml]

produces XHTML-compliant output.


例2: OOP スタイルで getOptDoc() を使う

<?php
class TidyOopDocFetcher
{
    private tidy $tidy;

    public function __construct()
    {
        $this->tidy = new tidy();
        $this->tidy->parseString('<html><body></body></html>', [], 'UTF8');
    }

    public function fetch(string $optname): string|false
    {
        return $this->tidy->getOptDoc($optname);
    }

    public function describeAll(array $optnames): void
    {
        foreach ($optnames as $opt) {
            $doc = $this->fetch($opt);
            printf(
                "%-25s => %s%s",
                $opt,
                $doc !== false ? $doc : '(説明なし)',
                PHP_EOL
            );
        }
    }
}

$fetcher = new TidyOopDocFetcher();
$fetcher->describeAll([
    'indent',
    'wrap',
    'tab-size',
    'output-xhtml',
    'char-encoding',
]);

出力例:

indent                    => indents each new tag for readability. default is auto.
wrap                      => sets the column at which line wrapping occurs.
tab-size                  => sets the number of spaces to indent.
output-xhtml              => produces XHTML-compliant output.
char-encoding             => set the input/output document encoding.

例3: 存在確認付きオプション検証クラス

<?php
class TidyOptionValidator
{
    private tidy $tidy;
    /** @var string[] */
    private array $valid   = [];
    /** @var string[] */
    private array $invalid = [];

    public function __construct()
    {
        $this->tidy = tidy_parse_string('<html><body></body></html>', [], 'UTF8');
    }

    public function validate(string ...$optnames): self
    {
        foreach ($optnames as $opt) {
            if (tidy_get_opt_doc($this->tidy, $opt) !== false) {
                $this->valid[] = $opt;
            } else {
                $this->invalid[] = $opt;
            }
        }
        return $this;
    }

    public function report(): void
    {
        echo "✅ 有効なオプション: " . implode(', ', $this->valid)   . PHP_EOL;
        echo "❌ 無効なオプション: " . implode(', ', $this->invalid) . PHP_EOL;
    }
}

$validator = new TidyOptionValidator();
$validator
    ->validate('indent', 'wrap', 'invalid-option', 'output-xhtml', 'fake-key')
    ->report();

出力例:

✅ 有効なオプション: indent, wrap, output-xhtml
❌ 無効なオプション: invalid-option, fake-key

例4: 複数オプションの説明を配列で収集するクラス

<?php
class TidyOptionDocCollector
{
    private tidy $tidy;

    public function __construct()
    {
        $this->tidy = tidy_parse_string('<html><body></body></html>', [], 'UTF8');
    }

    /**
     * @param string[] $optnames
     * @return array<string, string>
     */
    public function collect(array $optnames): array
    {
        $result = [];
        foreach ($optnames as $opt) {
            $doc = tidy_get_opt_doc($this->tidy, $opt);
            if ($doc !== false) {
                $result[$opt] = $doc;
            }
        }
        return $result;
    }

    public function toJson(array $optnames): string
    {
        return json_encode(
            $this->collect($optnames),
            JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT
        );
    }
}

$collector = new TidyOptionDocCollector();
echo $collector->toJson(['indent', 'wrap', 'output-xhtml']);

出力例:

{
    "indent": "indents each new tag for readability. default is auto.",
    "wrap": "sets the column at which line wrapping occurs.",
    "output-xhtml": "produces XHTML-compliant output."
}

例5: 設定候補の絞り込みと説明表示(検索クラス)

<?php
class TidyOptionSearcher
{
    private tidy $tidy;
    /** @var string[] */
    private readonly array $knownOptions;

    public function __construct()
    {
        $this->tidy = tidy_parse_string('<html><body></body></html>', [], 'UTF8');

        // 代表的な Tidy オプション一覧
        $this->knownOptions = [
            'indent', 'indent-spaces', 'wrap', 'wrap-attributes',
            'tab-size', 'output-xhtml', 'output-html', 'output-xml',
            'char-encoding', 'input-encoding', 'output-encoding',
            'newline', 'doctype', 'fix-uri', 'lowercase-tags',
            'uppercase-attributes', 'clean', 'drop-empty-elements',
            'show-warnings', 'quiet', 'tidy-mark',
        ];
    }

    /**
     * キーワードでオプション名と説明を絞り込む
     * @return array<string, string>
     */
    public function search(string $keyword): array
    {
        $result = [];
        foreach ($this->knownOptions as $opt) {
            $doc = tidy_get_opt_doc($this->tidy, $opt);
            if ($doc !== false && str_contains(strtolower($doc . $opt), strtolower($keyword))) {
                $result[$opt] = $doc;
            }
        }
        return $result;
    }

    public function printSearch(string $keyword): void
    {
        $hits = $this->search($keyword);
        echo "🔍 キーワード「{$keyword}」の検索結果: " . count($hits) . " 件" . PHP_EOL;
        foreach ($hits as $opt => $doc) {
            echo "  [{$opt}] {$doc}" . PHP_EOL;
        }
    }
}

$searcher = new TidyOptionSearcher();
$searcher->printSearch('encoding');

出力例:

🔍 キーワード「encoding」の検索結果: 3 件
  [char-encoding] set the input/output document encoding.
  [input-encoding] set the input document encoding.
  [output-encoding] set the output document encoding.

例6: 設定レポートを HTML テーブルで出力するクラス

<?php
class TidyOptionHtmlReporter
{
    private tidy $tidy;

    public function __construct()
    {
        $this->tidy = tidy_parse_string('<html><body></body></html>', [], 'UTF8');
    }

    public function generateTable(array $optnames): string
    {
        $rows = '';
        foreach ($optnames as $opt) {
            $doc = tidy_get_opt_doc($this->tidy, $opt);
            $desc = $doc !== false
                ? htmlspecialchars($doc, ENT_QUOTES, 'UTF-8')
                : '<em>説明なし</em>';
            $rows .= "<tr><td><code>{$opt}</code></td><td>{$desc}</td></tr>\n";
        }

        return <<<HTML
        <table border="1" cellpadding="6">
          <thead>
            <tr><th>オプション名</th><th>説明</th></tr>
          </thead>
          <tbody>
        {$rows}  </tbody>
        </table>
        HTML;
    }
}

$reporter = new TidyOptionHtmlReporter();
echo $reporter->generateTable(['indent', 'wrap', 'output-xhtml', 'char-encoding']);

出力例(HTML):

<table border="1" cellpadding="6">
  <thead>
    <tr><th>オプション名</th><th>説明</th></tr>
  </thead>
  <tbody>
    <tr><td><code>indent</code></td><td>indents each new tag for readability. default is auto.</td></tr>
    <tr><td><code>wrap</code></td><td>sets the column at which line wrapping occurs.</td></tr>
    <tr><td><code>output-xhtml</code></td><td>produces XHTML-compliant output.</td></tr>
    <tr><td><code>char-encoding</code></td><td>set the input/output document encoding.</td></tr>
  </tbody>
</table>

例7: オプション名の有効性チェック付き設定適用クラス

<?php
class TidyConfigApplier
{
    private tidy $tidy;
    /** @var array<string, mixed> */
    private array $appliedConfig = [];
    /** @var string[] */
    private array $skipped = [];

    public function __construct(private readonly string $html) {}

    /**
     * @param array<string, mixed> $config
     */
    public function apply(array $config): self
    {
        // 事前検証用の tidy オブジェクト
        $checker = tidy_parse_string('<html><body></body></html>', [], 'UTF8');

        foreach ($config as $opt => $value) {
            if (tidy_get_opt_doc($checker, $opt) !== false) {
                $this->appliedConfig[$opt] = $value;
            } else {
                $this->skipped[] = $opt;
            }
        }

        $this->tidy = tidy_parse_string($this->html, $this->appliedConfig, 'UTF8');
        $this->tidy->cleanRepair();
        return $this;
    }

    public function getOutput(): string
    {
        return tidy_get_output($this->tidy);
    }

    public function summary(): void
    {
        echo "✅ 適用オプション: " . implode(', ', array_keys($this->appliedConfig)) . PHP_EOL;
        echo "⚠️  スキップ:       " . (count($this->skipped) ? implode(', ', $this->skipped) : 'なし') . PHP_EOL;
    }
}

$html = '<html><body><p>Hello World</p></body></html>';

$applier = new TidyConfigApplier($html);
$applier->apply([
    'indent'        => true,
    'wrap'          => 80,
    'output-xhtml'  => true,
    'unknown-opt'   => 'value',   // 無効なオプション
]);

$applier->summary();
echo PHP_EOL . "=== 出力 HTML ===" . PHP_EOL;
echo $applier->getOutput();

出力例:

✅ 適用オプション: indent, wrap, output-xhtml
⚠️  スキップ:       unknown-opt

=== 出力 HTML ===
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html ...>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title></title>
  </head>
  <body>
    <p>Hello World</p>
  </body>
</html>

6. 関連関数との比較

関数名用途戻り値
tidy_get_opt_doc()オプションの説明文字列を取得string|false
tidy_getopt()オプションの現在値を取得mixed
tidy_setopt()オプションの値を設定bool
tidy_reset_config()すべてのオプションをデフォルトにリセットbool
tidy_get_config()現在の全設定を配列で取得array
tidy_get_release()Tidy ライブラリのリリース日付を取得string
tidy_get_html_ver()解析済み HTML のバージョン番号を取得int

7. よくある落とし穴と注意点

① 無効なオプション名では false が返る

存在しないオプション名を渡すと false が返ります。戻り値を文字列として直接使う前に必ず確認してください。

// NG: false が文字列として混入する
echo tidy_get_opt_doc($tidy, 'no-such-option'); // 何も表示しないか警告

// OK: 存在確認してから使う
$doc = tidy_get_opt_doc($tidy, 'no-such-option');
if ($doc !== false) {
    echo $doc;
}

② オプション名は大文字・小文字を区別する場合がある

Tidy のオプション名はハイフン区切りの小文字が基本です。"Indent""OUTPUT-XHTML" など大文字混じりは認識されないことがあります。

// NG: 大文字混じり
tidy_get_opt_doc($tidy, 'Indent');       // false になることがある

// OK: 小文字ハイフン区切り
tidy_get_opt_doc($tidy, 'indent');       // 正しく取得できる

③ 説明文は英語のみ

tidy_get_opt_doc() が返す説明文は Tidy ライブラリ内部の英語テキストです。日本語化は行われないため、多言語 UI に組み込む場合は独自の翻訳マッピングを用意してください。

④ tidy オブジェクトは必ず先に生成する

tidy_get_opt_doc() の第一引数には有効な tidy オブジェクトが必要です。new tidy() 直後の未解析状態でも動作することがありますが、tidy_parse_string() で確実に初期化してから使うことを推奨します。

// OK: parse 後に使う(推奨)
$tidy = tidy_parse_string('<html><body></body></html>', [], 'UTF8');
$doc  = tidy_get_opt_doc($tidy, 'indent');

8. まとめ

項目内容
主な用途Tidy オプションの説明文字列を動的に取得する
戻り値string(説明文)または false(オプション不存在)
OOP 版$tidy->getOptDoc(string $optname)
オプション名の書式小文字ハイフン区切り(例: output-xhtml, char-encoding
返される言語英語のみ(Tidy ライブラリ内部テキスト)
よく使う組み合わせtidy_getopt(), tidy_get_config(), tidy_setopt()

tidy_get_opt_doc() は、Tidy のオプション仕様をコード内で自己文書化したり、設定 UI を動的に構築したりする際に非常に便利な関数です。存在しないオプション名に対して false を返す性質を活かしたバリデーションに使う用途も実用的です。設定ミスを早期に検出する仕組みとして積極的に活用しましょう。

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