The pieces of WordPress, without the dependencies.
PHP Toolkit is a set of small, pure-PHP libraries for the work that WordPress core does every day — parsing HTML, reading ZIP archives, streaming bytes, importing content, making HTTP requests. No libxml2. No libzip. No curl. No database. Runs on PHP 7.2 through 8.3, on Linux, macOS, Windows, and inside the browser via WordPress Playground.
Where to start
The problem
The PHP ecosystem has spent twenty years assuming the host will provide the hard parts. Need to parse HTML? Install libxml2 and reach for DOMDocument. Need a ZIP? Hope ZipArchive is compiled in. Need to fetch a URL? Pray curl is available, then handle the cases where it isn't.
This works fine until it doesn't. Shared hosts disable extensions. WebAssembly runtimes don't have them at all. WordPress Playground runs in your browser and can't shell out to libzip. New PHP releases break old C bindings. Every extension is a dependency that some user, somewhere, can't satisfy.
Meanwhile WordPress core has quietly built its own answers: WP_HTML_Tag_Processor and WP_HTML_Processor for HTML, WP_Block_Parser for the editor's serialized content, hand-rolled archive helpers for plugin and theme updates. Pure PHP, no extensions, written carefully because they have to work everywhere from cheap shared hosting to a Raspberry Pi.
PHP Toolkit lifts those answers out of WordPress and turns them into libraries you can use anywhere.
The shape of it
Eighteen components. Each is a small library focused on one job, distributable as its own Composer package, depending only on PHP itself plus other toolkit components — no Composer packages outside the wp-php-toolkit/* family, no PHP extensions beyond json and mbstring.
All eighteen components
Content and migration
- HTMLBrowser-grade HTML5 parser and tag rewriter. Cursor model, byte-for-byte edits.
- BlockParserParse WordPress block markup into a structured tree.
- MarkdownBidirectional Markdown ↔ block markup with frontmatter as metadata.
- XMLStreaming, namespace-aware XML processor. Edit WXR exports without a tree.
- EncodingUTF-8 validation and scrubbing with a pure-PHP fallback.
- DataLiberationStream WordPress entities between sites; rewrite URLs across an export.
Streams and storage
- ByteStreamPull / peek / consume primitives. Gzip, hash, limit, window filters compose.
- FilesystemOne interface across disk, memory, SQLite, and ZIP-backed storage.
- ZipRead and write ZIP archives one entry at a time. EPUB, .docx, plugin bundles.
- GitPure-PHP Git: commits, branches, merges, HTTP push/pull, no shelling out.
- MergeThree-way diff and merge with explicit conflict records.
Networked tools
- HttpClientAsync HTTP with progress, redirects, ranged resume, concurrent requests.
- HttpServerTiny blocking TCP server for OAuth callbacks, fixtures, status pages.
- CORSProxyServer-side fetch for browser apps that can't bypass same-origin.
- CLIPOSIX argv parser. Long options, short bundles, one static call.
WordPress runtime support
The toolkit in one line each
preg_replace for HTML | → | HTML's WP_HTML_Tag_Processor rewrites attributes byte-for-byte without re-serializing. Untouched markup stays byte-identical. |
ZipArchive::open() | → | Zip's ZipFilesystem opens a 2 GB archive using memory proportional to the central directory's size, not the archive's. |
file_get_contents on a URL | → | HttpClient streams the response body, supports Range resume, reports progress, and uses curl when available or PHP stream sockets when it isn't. |
DOMDocument::loadHTML | → | HTML's WP_HTML_Processor parses HTML5 the way browsers do — fragments, implicit tags, the works. |
simplexml_load_string | → | XML's XMLProcessor walks WXR exports as a cursor and rewrites attributes byte-for-byte, never building a full tree. |
Credits
Several toolkit components are PHP ports or wrappers of upstream code:
- HTML is a port of WordPress core's
WP_HTML_Tag_ProcessorandWP_HTML_Processor. The toolkit version tracks core; bug fixes and improvements flow in both directions. Source: WordPress/wordpress-develop. - BlockParser is WordPress core's block parser (
WP_Block_Parser) packaged as a standalone library so importers and linters can read block markup without booting WordPress. Source: WordPress/wordpress-develop. - Markdown wraps
league/commonmarkfor the Markdown parsing itself andwebuni/front-matterfor the YAML frontmatter handling. The toolkit's own work is the bridge from CommonMark's AST into WordPress block markup, plus the reverse direction. - Polyfill's WordPress-shaped helpers (
esc_html,add_filter,__) defer to WordPress when WordPress is loaded. The standalone implementations match WordPress's behavior so the same code runs both inside and outside the platform.
The remaining components — Zip, ByteStream, Filesystem, XML, Encoding, DataLiberation, Git, Merge, HttpClient, HttpServer, CORSProxy, CLI, Blueprints, ToolkitCodingStandards — are toolkit originals, written for this project to fill gaps the PHP ecosystem leaves to extensions.
How the runnable examples work
Most code blocks on this site are <php-snippet> elements from WordPress Playground. Click Run and the page boots a PHP+WordPress runtime in your browser via WebAssembly, unzips the toolkit into it, and executes the snippet. The first run on a page boots the runtime; later runs reuse it. Edit the code in place and click Run again to see what changes.
Static code blocks show shell commands, deployment config, or network-bound code that needs a real local environment.