1. 関数概要
tidy_get_status は、PHP の Tidy 拡張が HTML/XHTML を解析した結果のステータスコードを整数値で返す関数です。解析が正常だったのか、警告があったのか、エラーがあったのかを数値で判定できるため、HTML バリデーションパイプラインやログ監視の起点として活用できます。
| 項目 | 内容 |
|---|---|
| 関数名 | tidy_get_status |
| 所属拡張 | Tidy |
| 戻り値の型 | int |
| 手続き型 / OOP | 手続き型(OOP 版: $tidy->getStatus()) |
| PHP バージョン | PHP 5 以降 |
| 公式ドキュメント | https://www.php.net/manual/ja/tidy.getstatus.php |
2. 構文
// 手続き型
tidy_get_status(tidy $tidy): int
// オブジェクト指向型
$tidy->getStatus(): int
パラメータ
| パラメータ | 型 | 説明 |
|---|---|---|
$tidy | tidy | tidy_parse_string() 等で生成した tidy オブジェクト |
戻り値
| 戻り値 | 意味 |
|---|---|
0 | エラーなし・警告なし(正常) |
1 | 警告あり(修復可能な問題が検出された) |
2 | エラーあり(深刻な問題が検出された) |
3. 動作概念図
┌──────────────────────────────────────────────────────────┐
│ HTML ソース文字列 │
└─────────────────────┬────────────────────────────────────┘
│ tidy_parse_string()
▼
┌──────────────────────────────────────────────────────────┐
│ Tidy 解析エンジン │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 構文チェック → エラー / 警告 を内部バッファに収集 │ │
│ └────────────────────────────────────────────────────┘ │
└─────────────────────┬────────────────────────────────────┘
│ tidy_get_status()
▼
┌───────────┼───────────┐
│ │ │
▼ ▼ ▼
戻り値: 0 戻り値: 1 戻り値: 2
正常 警告あり エラーあり
(errors=0 (警告のみ) (エラーを
warns=0) 含む)
※詳細は tidy_get_error_buffer() で確認できる
4. 基本的な使い方
<?php
$html = '<html><body><p>未閉じタグ<br></body></html>';
$tidy = tidy_parse_string($html, [], 'UTF8');
$status = tidy_get_status($tidy);
$label = match($status) {
0 => '✅ 正常',
1 => '⚠️ 警告あり',
2 => '❌ エラーあり',
default => '不明',
};
echo "ステータス: {$status} ({$label})" . PHP_EOL;
if ($status > 0) {
echo "--- エラーバッファ ---" . PHP_EOL;
echo tidy_get_error_buffer($tidy) . PHP_EOL;
}
出力例:
ステータス: 1 (⚠️ 警告あり)
--- エラーバッファ ---
line 1 column 28 - Warning: <br> inserting missing 'alt' attribute
5. 実践的なコード例
例1: ステータスに応じてメッセージを切り替えるクラス
<?php
class HtmlStatusChecker
{
private tidy $tidy;
private int $status;
private string $errorBuffer;
public function __construct(string $html, array $config = [])
{
$this->tidy = tidy_parse_string($html, $config, 'UTF8');
$this->status = tidy_get_status($this->tidy);
$this->errorBuffer = tidy_get_error_buffer($this->tidy) ?: '';
}
public function getStatus(): int
{
return $this->status;
}
public function isOk(): bool { return $this->status === 0; }
public function hasWarning(): bool { return $this->status === 1; }
public function hasError(): bool { return $this->status === 2; }
public function report(): void
{
$label = match($this->status) {
0 => '✅ 正常(エラー・警告なし)',
1 => '⚠️ 警告あり',
2 => '❌ エラーあり',
default => '不明',
};
echo "ステータス: {$label}" . PHP_EOL;
if ($this->status > 0 && $this->errorBuffer !== '') {
echo "詳細:" . PHP_EOL . $this->errorBuffer . PHP_EOL;
}
}
}
// 正常な HTML
$checker1 = new HtmlStatusChecker(
'<!DOCTYPE html><html><head><title>OK</title></head><body><p>正常</p></body></html>'
);
$checker1->report();
echo PHP_EOL;
// 問題のある HTML
$checker2 = new HtmlStatusChecker('<html><body><p>未閉じ<b>太字</body></html>');
$checker2->report();
出力例:
ステータス: ✅ 正常(エラー・警告なし)
ステータス: ⚠️ 警告あり
詳細:
line 1 column 26 - Warning: missing </b> before </body>
例2: OOP スタイルで getStatus() を使う
<?php
class TidyOopStatusFetcher
{
private tidy $tidy;
public function __construct(string $html, array $config = [])
{
$this->tidy = new tidy();
$this->tidy->parseString($html, $config, 'UTF8');
}
public function getStatus(): int
{
return $this->tidy->getStatus();
}
public function describe(): void
{
$status = $this->getStatus();
echo "OOP getStatus(): {$status}" . PHP_EOL;
echo match($status) {
0 => "→ 問題は検出されませんでした。",
1 => "→ 修復可能な警告が検出されました。",
2 => "→ 重大なエラーが検出されました。",
default => "→ 不明なステータスです。",
} . PHP_EOL;
}
}
$fetcher = new TidyOopStatusFetcher(
'<html><body><img src="photo.jpg"></body></html>'
);
$fetcher->describe();
出力例:
OOP getStatus(): 1
→ 修復可能な警告が検出されました。
例3: ステータス別に処理を分岐するパイプラインクラス
<?php
class HtmlValidationPipeline
{
public function run(string $html): void
{
$tidy = tidy_parse_string($html, ['indent' => true], 'UTF8');
$status = tidy_get_status($tidy);
match($status) {
0 => $this->onClean($tidy),
1 => $this->onWarning($tidy),
2 => $this->onError($tidy),
default => $this->onUnknown($status),
};
}
private function onClean(tidy $tidy): void
{
tidy_clean_repair($tidy);
echo "✅ クリーン: 修復済み HTML を出力します。" . PHP_EOL;
echo tidy_get_output($tidy) . PHP_EOL;
}
private function onWarning(tidy $tidy): void
{
tidy_clean_repair($tidy);
echo "⚠️ 警告: 修復して出力しますが、内容を確認してください。" . PHP_EOL;
echo "--- 警告内容 ---" . PHP_EOL;
echo tidy_get_error_buffer($tidy) . PHP_EOL;
}
private function onError(tidy $tidy): void
{
echo "❌ エラー: 出力をスキップします。" . PHP_EOL;
echo "--- エラー内容 ---" . PHP_EOL;
echo tidy_get_error_buffer($tidy) . PHP_EOL;
}
private function onUnknown(int $status): void
{
echo "不明なステータス: {$status}" . PHP_EOL;
}
}
$pipeline = new HtmlValidationPipeline();
$pipeline->run('<html><body><p>Hello</p></body></html>');
出力例:
✅ クリーン: 修復済み HTML を出力します。
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<p>Hello</p>
</body>
</html>
例4: 複数の HTML をバッチ検証してサマリーを表示するクラス
<?php
class HtmlBatchValidator
{
/** @var array<string, int> */
private array $results = [];
public function addAll(array $pages): self
{
foreach ($pages as $name => $html) {
$tidy = tidy_parse_string($html, [], 'UTF8');
$this->results[$name] = tidy_get_status($tidy);
}
return $this;
}
public function printSummary(): void
{
$counts = [0 => 0, 1 => 0, 2 => 0];
echo "=== バッチ検証サマリー ===" . PHP_EOL;
foreach ($this->results as $name => $status) {
$icon = match($status) { 0 => '✅', 1 => '⚠️ ', 2 => '❌', default => '?' };
printf(" %s %-20s status=%d%s", $icon, $name, $status, PHP_EOL);
$counts[$status] = ($counts[$status] ?? 0) + 1;
}
echo PHP_EOL;
echo "正常: {$counts[0]} 件 / 警告: {$counts[1]} 件 / エラー: {$counts[2]} 件" . PHP_EOL;
}
}
$validator = new HtmlBatchValidator();
$validator->addAll([
'index.html' => '<!DOCTYPE html><html><head><title>Top</title></head><body><p>OK</p></body></html>',
'about.html' => '<html><body><p>警告あり<br></body></html>',
'broken.html' => '<html><body><table><td>エラー</body></html>',
'contact.html' => '<!DOCTYPE html><html><head><title>Contact</title></head><body><p>OK</p></body></html>',
])->printSummary();
出力例:
=== バッチ検証サマリー ===
✅ index.html status=0
⚠️ about.html status=1
❌ broken.html status=2
✅ contact.html status=0
正常: 2 件 / 警告: 1 件 / エラー: 1 件
例5: ステータスとエラーバッファをセットでログ記録するクラス
<?php
class TidyStatusLogger
{
public function __construct(private readonly string $logFile) {}
public function validate(string $label, string $html): int
{
$tidy = tidy_parse_string($html, [], 'UTF8');
$status = tidy_get_status($tidy);
$errors = tidy_get_error_buffer($tidy) ?: '(なし)';
$statusLabel = match($status) {
0 => 'OK', 1 => 'WARN', 2 => 'ERROR', default => 'UNKNOWN',
};
$entry = sprintf(
"[%s] [%s] %s\n エラーバッファ: %s\n",
date('Y-m-d H:i:s'),
$statusLabel,
$label,
str_replace("\n", "\n ", trim($errors))
);
file_put_contents($this->logFile, $entry, FILE_APPEND);
echo $entry;
return $status;
}
}
$logger = new TidyStatusLogger('/tmp/tidy_status.log');
$logger->validate('ページA', '<!DOCTYPE html><html><head><title>A</title></head><body><p>OK</p></body></html>');
$logger->validate('ページB', '<html><body><p>未閉じ<b>太字</body></html>');
出力例:
[2026-07-09 12:00:00] [OK] ページA
エラーバッファ: (なし)
[2026-07-09 12:00:00] [WARN] ページB
エラーバッファ: line 1 column 22 - Warning: missing </b> before </body>
例6: ステータスに応じて例外を投げるバリデータクラス
<?php
class HtmlStrictValidator
{
private int $threshold;
/**
* @param int $threshold 許容するステータスの最大値(0=エラー・警告を許容しない, 1=警告まで許容)
*/
public function __construct(int $threshold = 1)
{
$this->threshold = $threshold;
}
public function validate(string $html): void
{
$tidy = tidy_parse_string($html, [], 'UTF8');
$status = tidy_get_status($tidy);
if ($status > $this->threshold) {
$errors = tidy_get_error_buffer($tidy) ?: '詳細不明';
throw new \RuntimeException(
"HTML バリデーション失敗 (status={$status}):\n{$errors}"
);
}
echo "✅ バリデーション通過 (status={$status})" . PHP_EOL;
}
}
// 警告まで許容するバリデータ
$validator = new HtmlStrictValidator(threshold: 1);
try {
$validator->validate('<html><body><p>警告あり<br></body></html>');
$validator->validate('<html><body><table><td>エラー</body></html>');
} catch (\RuntimeException $e) {
echo "❌ " . $e->getMessage() . PHP_EOL;
}
出力例:
✅ バリデーション通過 (status=1)
❌ HTML バリデーション失敗 (status=2):
line 1 column 22 - Error: <td> is not allowed here
...
例7: 解析結果をまとめて返す統合レポートクラス
<?php
readonly class TidyReport
{
public function __construct(
public int $status,
public string $statusLabel,
public string $errorBuffer,
public int $htmlVersion,
public string $release,
public string $output,
) {}
}
class TidyReporter
{
public function analyze(string $html, array $config = []): TidyReport
{
$tidy = tidy_parse_string($html, $config + ['indent' => true], 'UTF8');
tidy_clean_repair($tidy);
$status = tidy_get_status($tidy);
return new TidyReport(
status: $status,
statusLabel: match($status) { 0 => 'OK', 1 => 'WARN', 2 => 'ERROR', default => 'UNKNOWN' },
errorBuffer: tidy_get_error_buffer($tidy) ?: '',
htmlVersion: tidy_get_html_ver($tidy),
release: tidy_get_release(),
output: tidy_get_output($tidy),
);
}
public function printReport(TidyReport $report): void
{
echo "=== Tidy 統合レポート ===" . PHP_EOL;
echo "ステータス : {$report->status} ({$report->statusLabel})" . PHP_EOL;
echo "HTML バージョン: {$report->htmlVersion}" . PHP_EOL;
echo "libtidy : {$report->release}" . PHP_EOL;
echo "エラーバッファ : " . ($report->errorBuffer ?: '(なし)') . PHP_EOL;
echo "--- 整形済み出力(先頭200文字)---" . PHP_EOL;
echo substr($report->output, 0, 200) . PHP_EOL;
}
}
$reporter = new TidyReporter();
$report = $reporter->analyze('<html><body><p>サンプル</p></body></html>');
$reporter->printReport($report);
出力例:
=== Tidy 統合レポート ===
ステータス : 0 (OK)
HTML バージョン: 0
libtidy : 1st August 2023
エラーバッファ : (なし)
--- 整形済み出力(先頭200文字)---
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<p>サンプル</p>
</body>
</html>
6. 関連関数との比較
| 関数名 | 用途 | 戻り値 |
|---|---|---|
tidy_get_status() | 解析ステータスコードを取得(0/1/2) | int |
tidy_get_error_buffer() | エラー・警告の詳細メッセージを取得 | string|false |
tidy_error_count() | エラーの件数を取得 | int |
tidy_warning_count() | 警告の件数を取得 | int |
tidy_access_count() | アクセシビリティ警告の件数を取得 | int |
tidy_get_output() | 整形済み HTML 文字列を取得 | string |
tidy_get_html_ver() | 解析済み HTML のバージョン番号を取得 | int |
tidy_get_release() | libtidy のリリース日付を取得 | string |
使い分けのポイント:
tidy_get_status()は「問題があるかどうか」の素早い判定に使い、「何件あるか」を知りたい場合はtidy_error_count()/tidy_warning_count()、「どんな問題か」を知りたい場合はtidy_get_error_buffer()と組み合わせます。
7. よくある落とし穴と注意点
① ステータス 0 でも完全に正しい HTML とは限らない
Tidy が警告・エラーと判定しないだけであり、HTML として意味的に正しいことを保証するものではありません。セマンティクスの検証には別途チェックが必要です。
② tidy_clean_repair() の前後でステータスが変わることがある
tidy_get_status() は解析時点(tidy_parse_string())のステータスを返します。tidy_clean_repair() を呼ぶと内部状態が変化し、ステータスが更新されることがあります。ステータスを確認するタイミングに注意してください。
$tidy = tidy_parse_string($html, [], 'UTF8');
$before = tidy_get_status($tidy); // 修復前のステータス
tidy_clean_repair($tidy);
$after = tidy_get_status($tidy); // 修復後のステータス(変化する場合がある)
③ 戻り値は int だが bool として扱うと意図しない動作になる
0 は false 相当、1 や 2 は true 相当に評価されます。if ($status) のような判定は「問題あり」の検出に使えますが、1(警告)と 2(エラー)を区別したい場合は === で明示的に比較してください。
// NG: 1 と 2 を区別できない
if (tidy_get_status($tidy)) { echo "問題あり"; }
// OK: 明示的に比較
$status = tidy_get_status($tidy);
if ($status === 2) { echo "エラーあり"; }
elseif ($status === 1) { echo "警告あり"; }
④ エラー件数が知りたい場合は別関数を使う
tidy_get_status() は件数ではなくステータスコードを返します。件数が必要な場合は tidy_error_count() や tidy_warning_count() を使ってください。
$tidy = tidy_parse_string($html, [], 'UTF8');
echo "エラー件数 : " . tidy_error_count($tidy) . PHP_EOL;
echo "警告件数 : " . tidy_warning_count($tidy) . PHP_EOL;
echo "ステータス : " . tidy_get_status($tidy) . PHP_EOL;
8. まとめ
| 項目 | 内容 |
|---|---|
| 主な用途 | Tidy による HTML 解析結果のステータスを素早く判定する |
| 戻り値 | 0=正常 / 1=警告あり / 2=エラーあり |
| OOP 版 | $tidy->getStatus() |
| 詳細確認 | tidy_get_error_buffer() と組み合わせる |
| 件数確認 | tidy_error_count() / tidy_warning_count() を使う |
| 注意点 | bool 評価で 1 と 2 を混同しない・clean_repair 前後でステータスが変わることがある |
tidy_get_status() は HTML バリデーションの最初の判断ゲートとして機能する関数です。0・1・2 の3値で問題の有無を素早く判定し、問題がある場合は tidy_get_error_buffer() で詳細を確認する、という2段構えのパターンが実践的な定番の使い方です。
