voku/simple_html_dom
voku/simple_html_dom is a fast PHP HTML DOM parser and jQuery-style selector library. It wraps DOMDocument and Symfony CssSelector to find, extract, and manipulate HTML with UTF-8 and partial invalid-HTML support. Requires PHP 7.1+.
Architecture fit. voku/simple_html_dom is a framework-agnostic, leaf-level PHP library — a maintained fork of the abandoned PHP Simple HTML DOM Parser that swaps the original's string-manipulation engine for ext-dom/DOMDocument. It has no Laravel service provider, no facades, and no framework coupling, which is actually the right shape for a TPM to own: it belongs behind an application-level adapter (an HtmlParserContract binding) rather than being sprinkled through controllers and jobs. Its natural home is ingestion work — scraping partners, parsing email/HTML templates, normalizing CMS output, or extracting structured data from semi-structured documents — not as a rendering or sanitization layer (use HTMLPurifier/symfony/html-sanitizer for that).
Integration feasibility. composer require voku/simple_html_dom is a two-minute change. The real work is environmental verification: it requires ext-dom and ext-mbstring, and older tagged releases support PHP 7.x while recent ones target 8.x — confirm the constraint against the Laravel version in use (Laravel 9/10/11 on PHP 8.1+ is the comfortable band). No published Laravel auto-discovery, so if the team wants DI, they write a ~15-line service provider themselves.
Technical risk. Three risks a TPM should log and assign:
Dependents: 0 and maturity flagged as readme — I would treat both as insufficient evidence of ecosystem validation rather than proof of disuse, and independently verify against Packagist download volume before committing. Either way, budget for a possible internal fork.DOMDocument requires deliberate configuration; the library mitigates much of this but the TPM should require an explicit test for XXE and billion-laughs before any user-supplied HTML is parsed.Key questions for the owning team. Do we need jQuery-style manipulation (this library's strength) or merely querying? If it's querying plus CSS selectors, symfony/dom-crawler is first-party maintained and is the lower-risk default — that's the primary build-vs-adopt decision. Second: what is the maximum document size and throughput we must survive? Third: who is the named internal owner and what is the review cadence? Fourth: what PHP/Apache-FPM image family do we deploy, and are the required extensions present in the slim variants?
Stack fit. Composer-native, PSR-4 (voku\helper\HtmlDomParser), zero framework dependencies, MIT — no licensing review friction. It composes cleanly with Laravel's queue, storage, and HTTP client layers, which is where a parser of this kind actually gets used.
Migration path. Wrap it immediately: define an interface (parse(string $html): HtmlDocument), implement it with voku/simple_html_dom, and bind it in a service provider. That single decision converts an irreversible dependency choice into a swappable one and lets you A/B the library against symfony/dom-crawler on real fixtures later. If the codebase currently uses sunra/php-simple-html-dom-parser or the legacy simplehtmldom, the API surface is largely source-compatible — the migration is namespace replacement plus removal of deprecated calls, not a rewrite.
Compatibility. Check three things before merge: composer.json PHP floor vs. the project's minimum, presence of ext-dom/ext-mbstring in the production image, and any transitive conflict with symfony/dom-crawler if that package is already present (it usually isn't — this library is self-contained). Note that the fork deliberately retains the legacy jQuery-like API, so expect some non-idiomatic PHP 8 signatures; gate with static analysis (PHPStan/Psalm) at a baseline level rather than blocking on it.
Sequencing.
voku/simple_html_dom vs. symfony/dom-crawler, decided on measured accuracy and memory, not preference.Maintenance. Low churn, low surface area — but a single-maintainer project. Operationalize that: pin an exact version in composer.lock, run composer audit in CI, and put the package on a quarterly review list with a documented fallback (internal fork under our org, MIT permits it). Keep the adapter thin so a fork swap is a one-file change.
Support. Community-only (GitHub issues), no vendor SLA. The TPM lever here is internal: a short internal README covering the encoding and malformed-HTML gotchas, plus fixtures, so the knowledge isn't resident in one engineer.
Scaling. Parsing is CPU- and memory-bound — DOMDocument builds a full tree, so cost scales with document size, not with the fields you actually want. Never run it in the request cycle; run it in queued jobs with explicit timeouts and memory ceilings. For documents above roughly 1–2 MB, or for streaming feeds, this is the wrong tool — plan a XMLReader/SAX path or targeted regex extraction instead. Cache parsed/normalized output where the same source is re-read.
Failure modes to instrument. (a) Silent partial parses on malformed input — assert on expected node counts, not just "no exception"; (b) character-encoding mismatch producing mojibake — normalize to UTF-8 at the boundary and fail loudly on conversion error; (c) memory exhaustion on oversized documents — enforce an input size cap before handing HTML to the parser; (d) unhandled behavior on XML/entity edge cases for untrusted input — regression-test explicitly; (e) PHP 8 deprecation noise from legacy signatures — track via static analysis so it doesn't mask real regressions.
Ramp-up. Very shallow — the jQuery-style selector API is intuitive and a mid-level Laravel developer is productive in under a day. The actual onboarding cost is not the API but the failure semantics: teams must learn that this parser degrades quietly, and that validation belongs in the adapter, not in the caller.
How can I help you explore Laravel packages today?