Heading Outline Auditor
Checks H1/H2/H3 structure for missing, duplicate, or illogical headings.
Function signature
ogAuditHeadingOutline(html)
Categories
- SEO and Routing
Parameters
htmlHTML fragment to inspect for heading outline problems.Return value
Public-safe status string returned by the function for controller branching or logging.
- success
- message
- data
Compatibility
Existing function name, slug, path, and call order preserved; advertised metadata corrected to the actual source behavior.
Minimum PHP version: 7.4
Security notes
Use caller-owned allowlists and context-specific escaping; validate file paths, routes, email tokens, cart totals, discount rules, and tax-region rules before production use.
Code
<?php
/*
* Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
* Free for personal and internal use. Paid project use requires visible credit
* to Jeffery L. Paris. Corporate use requires a paid license fee unless a
* separate written license states otherwise.
*/
/**
* Checks H1/H2/H3 structure for missing, duplicate, or illogical headings.
*
* Primary use case: SEO/content QA.
* Typical inputs: HTML or parsed headings.
* Typical output: outline report.
*
* Implementation note: Use as audit; do not auto-rewrite content blindly.
*
* @param string $html HTML content to audit.
* @return array Heading outline audit report.
*/
function ogAuditHeadingOutline($html) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
$html = (string)$html;
if (empty($html)) {
$result['message'] = 'HTML content is required.';
return $result;
}
$matches = array();
preg_match_all('/<h([1-3])[^>]*>(.*?)<\/h\1>/is', $html, $matches, PREG_SET_ORDER);
$headings = array();
$warnings = array();
$h1_count = 0;
$last_level = 0;
foreach ($matches as $match) {
$level = (int)$match[1];
$text = trim(strip_tags($match[2]));
if ($level == 1) {
$h1_count++;
}
if ($last_level > 0 && $level > ($last_level + 1)) {
$warnings[] = 'Heading level jumps from H' . $last_level . ' to H' . $level . '.';
}
$last_level = $level;
$headings[] = array('level' => $level, 'text' => $text);
}
if ($h1_count == 0) {
$warnings[] = 'Missing H1 heading.';
}
if ($h1_count > 1) {
$warnings[] = 'Multiple H1 headings detected.';
}
$result['success'] = true;
$result['message'] = 'Heading outline audited.';
$result['data'] = array(
'headings' => $headings,
'h1_count' => $h1_count,
'warnings' => $warnings
);
return $result;
}