[PHP]tidy_getopt完全解説|Tidyオプションの現在値を取得して設定内容を動的に確認する方法

PHP

1. 関数概要

tidy_getopt は、PHP の Tidy 拡張に設定されているオプションの現在値を取得する関数です。オプション名を文字列で渡すと、そのオプションに現在セットされている値を返します。設定内容のデバッグ・ログ記録・動的な条件分岐など、オプション値を実行時に確認したい場面で活用できます。

項目内容
関数名tidy_getopt
所属拡張Tidy
戻り値の型mixedbool / int / string のいずれか)
手続き型 / OOP手続き型(OOP 版: $tidy->getOpt(string $option)
PHP バージョンPHP 5 以降
公式ドキュメントhttps://www.php.net/manual/ja/tidy.getopt.php

2. 構文

// 手続き型
tidy_getopt(tidy $tidy, string $option): mixed

// オブジェクト指向型
$tidy->getOpt(string $option): mixed

パラメータ

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

戻り値

オプションの型によって戻り値の型が異なります。

オプションの型戻り値の型
ブール型オプションbooltrue / false
整数型オプションint80, 4 など
文字列型オプションstring"utf8", "auto" など
無効なオプション名false

3. 動作概念図

tidy_parse_string($html, ['indent' => true, 'wrap' => 120], 'UTF8')
        │
        ▼
┌──────────────────────────────────────────────────────────┐
│  tidy オブジェクト(内部オプションテーブル)              │
│  ┌────────────────┬───────────┬────────────────────────┐ │
│  │ オプション名   │ 型        │ 現在値                  │ │
│  ├────────────────┼───────────┼────────────────────────┤ │
│  │ indent         │ bool      │ true                   │ │
│  │ indent-spaces  │ int       │ 2(デフォルト)         │ │
│  │ wrap           │ int       │ 120                    │ │
│  │ output-xhtml   │ bool      │ false(デフォルト)     │ │
│  │ char-encoding  │ string    │ "utf8"                 │ │
│  │ ...            │ ...       │ ...                    │ │
│  └────────────────┴───────────┴────────────────────────┘ │
└─────────────────────┬────────────────────────────────────┘
                      │ tidy_getopt($tidy, 'wrap')
                      ▼
              戻り値: 120 (int)

4. 基本的な使い方

<?php
$html   = '<html><body><p>サンプル</p></body></html>';
$config = ['indent' => true, 'wrap' => 120, 'output-xhtml' => false];

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

// 各オプションの現在値を取得
$indent      = tidy_getopt($tidy, 'indent');
$wrap        = tidy_getopt($tidy, 'wrap');
$outputXhtml = tidy_getopt($tidy, 'output-xhtml');
$encoding    = tidy_getopt($tidy, 'char-encoding');

echo "indent       : " . var_export($indent, true)      . PHP_EOL;
echo "wrap         : " . $wrap                           . PHP_EOL;
echo "output-xhtml : " . var_export($outputXhtml, true) . PHP_EOL;
echo "char-encoding: " . $encoding                       . PHP_EOL;

出力例:

indent       : true
wrap         : 120
output-xhtml : false
char-encoding: utf8

5. 実践的なコード例

例1: 設定値を一覧表示するクラス

<?php
class TidyOptionDumper
{
    private tidy $tidy;

    /** @var string[] */
    private array $optionNames = [
        'indent', 'indent-spaces', 'wrap', 'tab-size',
        'output-xhtml', 'output-html', 'output-xml',
        'char-encoding', 'input-encoding', 'output-encoding',
        'doctype', 'fix-uri', 'lowercase-tags',
        'clean', 'drop-empty-elements', 'show-warnings', 'quiet',
    ];

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

    public function dump(): void
    {
        echo "=== Tidy オプション現在値一覧 ===" . PHP_EOL;
        foreach ($this->optionNames as $opt) {
            $val = tidy_getopt($this->tidy, $opt);
            printf(
                "  %-25s : %s%s",
                $opt,
                var_export($val, true),
                PHP_EOL
            );
        }
    }
}

$dumper = new TidyOptionDumper(
    '<html><body><p>テスト</p></body></html>',
    ['indent' => true, 'wrap' => 80, 'output-xhtml' => true]
);
$dumper->dump();

出力例:

=== Tidy オプション現在値一覧 ===
  indent                    : true
  indent-spaces             : 2
  wrap                      : 80
  tab-size                  : 8
  output-xhtml              : true
  output-html               : false
  output-xml                : false
  char-encoding             : 'utf8'
  input-encoding            : 'latin1'
  output-encoding           : 'ascii'
  doctype                   : 'auto'
  fix-uri                   : true
  lowercase-tags            : true
  clean                     : false
  drop-empty-elements       : true
  show-warnings             : true
  quiet                     : false

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

<?php
class TidyOopOptFetcher
{
    private tidy $tidy;

    public function __construct(string $html, array $config = [])
    {
        $this->tidy = new tidy();
        $this->tidy->parseString($html, $config, 'UTF8');
    }

    public function get(string $option): mixed
    {
        return $this->tidy->getOpt($option);
    }

    public function compare(string $option, mixed $expected): void
    {
        $actual = $this->get($option);
        $match  = $actual === $expected ? '✅ 一致' : '❌ 不一致';
        printf(
            "[%s] %s => 期待値: %s / 実際: %s%s",
            $match,
            $option,
            var_export($expected, true),
            var_export($actual, true),
            PHP_EOL
        );
    }
}

$fetcher = new TidyOopOptFetcher(
    '<html><body></body></html>',
    ['indent' => true, 'wrap' => 80]
);

$fetcher->compare('indent', true);
$fetcher->compare('wrap', 80);
$fetcher->compare('output-xhtml', false);
$fetcher->compare('quiet', false);

出力例:

[✅ 一致] indent => 期待値: true / 実際: true
[✅ 一致] wrap => 期待値: 80 / 実際: 80
[✅ 一致] output-xhtml => 期待値: false / 実際: false
[✅ 一致] quiet => 期待値: false / 実際: false

例3: 設定値を検証してから処理を進めるクラス

<?php
class TidyConfigGuard
{
    private tidy $tidy;

    public function __construct(string $html, private readonly array $config)
    {
        $this->tidy = tidy_parse_string($html, $this->config, 'UTF8');
    }

    /**
     * @param array<string, mixed> $requirements  期待するオプション値の連想配列
     */
    public function assertOptions(array $requirements): void
    {
        $failures = [];
        foreach ($requirements as $opt => $expected) {
            $actual = tidy_getopt($this->tidy, $opt);
            if ($actual !== $expected) {
                $failures[] = sprintf(
                    "%s: 期待=%s / 実際=%s",
                    $opt,
                    var_export($expected, true),
                    var_export($actual, true)
                );
            }
        }

        if (count($failures) > 0) {
            throw new \UnexpectedValueException(
                "オプション設定の不整合:\n" . implode("\n", $failures)
            );
        }

        echo "✅ すべてのオプションが期待値と一致しています。" . PHP_EOL;
    }
}

$guard = new TidyConfigGuard(
    '<html><body><p>テスト</p></body></html>',
    ['indent' => true, 'wrap' => 80, 'output-xhtml' => false]
);

try {
    $guard->assertOptions([
        'indent'       => true,
        'wrap'         => 80,
        'output-xhtml' => false,
    ]);

    // 意図的に不一致を起こす
    $guard->assertOptions([
        'wrap' => 120,  // 実際は 80 なので不一致
    ]);
} catch (\UnexpectedValueException $e) {
    echo "❌ " . $e->getMessage() . PHP_EOL;
}

出力例:

✅ すべてのオプションが期待値と一致しています。
❌ オプション設定の不整合:
wrap: 期待=120 / 実際=80

例4: オプションの型を判定して安全に使うクラス

<?php
class TidyOptTypeResolver
{
    private tidy $tidy;

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

    public function getTyped(string $option): array
    {
        $val  = tidy_getopt($this->tidy, $option);
        $type = match(true) {
            $val === false && tidy_get_opt_doc($this->tidy, $option) === false
                          => 'invalid',
            is_bool($val) => 'bool',
            is_int($val)  => 'int',
            is_string($val) => 'string',
            default       => 'unknown',
        };

        return ['option' => $option, 'value' => $val, 'type' => $type];
    }

    public function printTyped(string ...$options): void
    {
        foreach ($options as $opt) {
            $info = $this->getTyped($opt);
            printf(
                "  %-20s [%-7s] = %s%s",
                $info['option'],
                $info['type'],
                var_export($info['value'], true),
                PHP_EOL
            );
        }
    }
}

$resolver = new TidyOptTypeResolver(
    '<html><body></body></html>',
    ['indent' => true, 'wrap' => 80, 'char-encoding' => 'utf8']
);

$resolver->printTyped(
    'indent',
    'wrap',
    'char-encoding',
    'indent-spaces',
    'output-xhtml',
    'no-such-option'
);

出力例:

  indent               [bool   ] = true
  wrap                 [int    ] = 80
  char-encoding        [string ] = 'utf8'
  indent-spaces        [int    ] = 2
  output-xhtml         [bool   ] = false
  no-such-option       [invalid] = false

例5: 設定変更前後の値を比較するクラス

<?php
class TidyOptionChangeTracker
{
    /** @var array<string, mixed> */
    private array $before = [];

    public function snapshot(tidy $tidy, array $optionNames): self
    {
        foreach ($optionNames as $opt) {
            $this->before[$opt] = tidy_getopt($tidy, $opt);
        }
        return $this;
    }

    public function diff(tidy $tidyAfter): void
    {
        echo "=== オプション変更前後の比較 ===" . PHP_EOL;
        $changed = false;
        foreach ($this->before as $opt => $beforeVal) {
            $afterVal = tidy_getopt($tidyAfter, $opt);
            $mark     = $beforeVal === $afterVal ? '  (変化なし)' : '  ← 変更あり';
            printf(
                "  %-20s: %s → %s%s%s",
                $opt,
                var_export($beforeVal, true),
                var_export($afterVal, true),
                $mark,
                PHP_EOL
            );
            if ($beforeVal !== $afterVal) { $changed = true; }
        }
        echo $changed ? PHP_EOL . "変更されたオプションがあります。" . PHP_EOL
                      : PHP_EOL . "すべてのオプションは同じです。"   . PHP_EOL;
    }
}

$opts    = ['indent', 'wrap', 'output-xhtml', 'char-encoding'];
$html    = '<html><body><p>比較テスト</p></body></html>';

$tidyA   = tidy_parse_string($html, ['indent' => false, 'wrap' => 68], 'UTF8');
$tracker = new TidyOptionChangeTracker();
$tracker->snapshot($tidyA, $opts);

$tidyB   = tidy_parse_string($html, ['indent' => true, 'wrap' => 120, 'output-xhtml' => true], 'UTF8');
$tracker->diff($tidyB);

出力例:

=== オプション変更前後の比較 ===
  indent              : false → true    ← 変更あり
  wrap                : 68 → 120        ← 変更あり
  output-xhtml        : false → true    ← 変更あり
  char-encoding       : 'utf8' → 'utf8'   (変化なし)

変更されたオプションがあります。

例6: オプション値を JSON でエクスポートするクラス

<?php
class TidyOptJsonExporter
{
    private tidy $tidy;

    /** @var string[] */
    private array $targets = [
        'indent', 'indent-spaces', 'wrap', 'tab-size',
        'output-xhtml', 'output-html', 'output-xml',
        'char-encoding', 'doctype', 'fix-uri',
        'lowercase-tags', 'clean', 'show-warnings', 'quiet',
    ];

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

    public function export(): string
    {
        $data = [];
        foreach ($this->targets as $opt) {
            $val = tidy_getopt($this->tidy, $opt);
            if ($val !== false) {
                $data[$opt] = $val;
            }
        }
        return json_encode(
            ['options' => $data, 'exported_at' => date('c')],
            JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
        );
    }
}

$exporter = new TidyOptJsonExporter(
    '<html><body></body></html>',
    ['indent' => true, 'wrap' => 100, 'output-xhtml' => true]
);
echo $exporter->export();

出力例:

{
    "options": {
        "indent": true,
        "indent-spaces": 2,
        "wrap": 100,
        "tab-size": 8,
        "output-xhtml": true,
        "output-html": false,
        "output-xml": false,
        "char-encoding": "utf8",
        "doctype": "auto",
        "fix-uri": true,
        "lowercase-tags": true,
        "clean": false,
        "show-warnings": true,
        "quiet": false
    },
    "exported_at": "2026-07-09T12:00:00+09:00"
}

例7: オプション値に応じて出力形式を自動選択するクラス

<?php
class TidyAdaptiveFormatter
{
    private tidy $tidy;

    public function __construct(string $html, array $config = [])
    {
        $this->tidy = tidy_parse_string($html, $config, 'UTF8');
        tidy_clean_repair($this->tidy);
    }

    public function format(): string
    {
        $isXhtml  = (bool) tidy_getopt($this->tidy, 'output-xhtml');
        $isXml    = (bool) tidy_getopt($this->tidy, 'output-xml');
        $wrap     = (int)  tidy_getopt($this->tidy, 'wrap');
        $indent   = (bool) tidy_getopt($this->tidy, 'indent');

        $mode = match(true) {
            $isXhtml => 'XHTML',
            $isXml   => 'XML',
            default  => 'HTML',
        };

        echo "出力モード : {$mode}" . PHP_EOL;
        echo "インデント : " . ($indent ? 'あり' : 'なし') . PHP_EOL;
        echo "折り返し幅 : {$wrap}" . PHP_EOL . PHP_EOL;

        return tidy_get_output($this->tidy);
    }
}

$formatter = new TidyAdaptiveFormatter(
    '<html><body><p>自動選択サンプル</p></body></html>',
    ['output-xhtml' => true, 'indent' => true, 'wrap' => 60]
);

echo $formatter->format();

出力例:

出力モード : XHTML
インデント : あり
折り返し幅 : 60

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ...>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title></title>
</head>
<body>
  <p>自動選択サンプル</p>
</body>
</html>

6. 関連関数との比較

関数名用途戻り値
tidy_getopt()オプションの現在値を取得mixedbool/int/string/false
tidy_get_opt_doc()オプションの説明文を取得string|false
tidy_get_config()現在の全オプションを連想配列で取得array
tidy_setopt()オプションの値を設定bool
tidy_reset_config()全オプションをデフォルトにリセットbool
tidy_get_status()解析ステータスコードを取得int

使い分けのポイント: 単一オプションの現在値を知りたいときは tidy_getopt()、全オプションを一括取得したいときは tidy_get_config() が便利です。


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

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

存在しないオプション名を渡すと false が返ります。ブール型オプション(false が正常値として返りうる)と混同しないよう、tidy_get_opt_doc() で存在確認を行ってください。

// NG: false がエラーなのか bool(false) なのか区別できない
$val = tidy_getopt($tidy, 'output-xhtml'); // false → オフ or 無効?

// OK: 存在確認と組み合わせる
if (tidy_get_opt_doc($tidy, 'output-xhtml') !== false) {
    $val = tidy_getopt($tidy, 'output-xhtml'); // false → 確実にオフ
}

② ブール型オプションの false と「オプション不存在の false」を区別する

tidy_getopt() は無効なオプション名にも false を返します。戻り値が false の場合は必ず tidy_get_opt_doc() で存在を確認してから判断してください(上記と同様)。

③ オプション名は小文字ハイフン区切りが基本

"indentSpaces""Indent" のようなキャメルケース・パスカルケースは認識されません。

tidy_getopt($tidy, 'indent-spaces'); // ✅ 正しい
tidy_getopt($tidy, 'indentSpaces');  // ❌ false が返る

④ tidy_getopt() はスナップショットではない

tidy_parse_string() に渡した設定が反映された値を返しますが、tidy_setopt() で後から値を変更した場合は変更後の値が返ります。取得タイミングに注意してください。


8. まとめ

項目内容
主な用途Tidy オプションの現在値を個別に取得する
戻り値の型bool / int / string(オプション型に依存)、無効名の場合は false
OOP 版$tidy->getOpt(string $option)
全件取得tidy_get_config() を使う
説明文取得tidy_get_opt_doc() を使う
注意点無効名も false を返す・オプション名は小文字ハイフン区切り

tidy_getopt() は Tidy の設定状態をピンポイントで確認できる関数です。tidy_get_opt_doc() による存在確認や tidy_get_config() による全件取得と組み合わせることで、設定ミスの早期検出や動的な出力制御を柔軟に実装できます。

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