PHP Toolkit

Experimental native PHP build

Compile wp_native_apis for host PHP.

Use this guide when you want the Rust-backed Native APIs extension on a local PHP CLI or server. The build is tied to the PHP version and platform you compile against, so treat it as a development and benchmarking path until packaged host releases are published.

What you will build

The host PHP extension is the Rust-backed implementation built with ext-php-rs. When it is loaded before the toolkit bootstrap, covered HTML, XML, and URL-in-text classes can delegate hot paths to native code. If the extension is absent, incompatible, or disabled, the public PHP APIs keep using their pure-PHP fallback implementations.

Not the Playground build: WordPress Playground uses a PHP.wasm extension bundle. This page is for native host PHP, such as a local Linux PHP CLI with development headers.

Prerequisites

On Ubuntu, the CI benchmark job installs the native build dependencies like this:

sudo apt-get update
sudo apt-get install -y clang libclang-dev
composer install --prefer-dist --no-progress --no-suggest

On other systems, install equivalent PHP development headers, Rust, Cargo, Clang, and libclang. If php-config or libclang are not discoverable, pass their paths explicitly in the build step.

Build the extension

Run the helper script from the repository root:

extensions/native-apis/build-extension.sh

If your target PHP is not the first php-config on PATH, point the build at the exact one you want:

PHP_CONFIG=/path/to/php-config \
LIBCLANG_PATH=/path/to/libclang/lib \
extensions/native-apis/build-extension.sh

The documented Linux build writes the shared object here:

extensions/native-apis/target/release/libwp_native_apis.so

Use the same PHP binary at runtime that matches the php-config used at build time. Native PHP extensions are ABI-specific; do not reuse one shared object across PHP versions.

Verify that PHP can load it

Load the extension before running the native verifier:

php -d extension=extensions/native-apis/target/release/libwp_native_apis.so \
	extensions/native-apis/tests/verify-native-apis.php

A successful run means PHP loaded the extension and the expected native classes are registered. If the script reports that the extension is unavailable, re-check the PHP version, php-config path, shared-object path, and libclang setup.

Use it through the public toolkit classes

Load the extension before the toolkit bootstrap. The public wrappers decide whether a native delegate is available and fall back to PHP when it is not.

php -d extension=extensions/native-apis/target/release/libwp_native_apis.so <<'PHP'
<?php
require __DIR__ . '/bootstrap.php';

var_dump( is_subclass_of( 'WP_HTML_Tag_Processor', 'WP_HTML_Native_Tag_Processor' ) );
var_dump( is_subclass_of( 'WordPress\\XML\\XMLProcessor', 'WordPress\\XML\\NativeXMLProcessor' ) );
PHP

To force the safe pure-PHP path for comparison, define WP_NATIVE_APIS_DISABLE_DEFAULTS before loading the toolkit:

php -d extension=extensions/native-apis/target/release/libwp_native_apis.so <<'PHP'
<?php
define( 'WP_NATIVE_APIS_DISABLE_DEFAULTS', true );
require __DIR__ . '/bootstrap.php';

var_dump( is_subclass_of( 'WP_HTML_Tag_Processor', 'WP_HTML_Native_Tag_Processor' ) );
PHP

Run the benchmark

The same benchmark command runs in CI for the release page. It requires the native classes, compares PHP and native modes, and disables native defaults so both paths are measured deliberately.

php -d extension=extensions/native-apis/target/release/libwp_native_apis.so \
	bin/benchmark-native-apis.php \
	--iterations=50 \
	--mode=both \
	--disable-native-defaults \
	--require-native

Benchmark numbers are machine-specific. Use them to compare PHP and native behavior on the same machine, not as universal throughput guarantees.

Troubleshooting

php-config was not found

Install PHP development headers for the PHP version you want to target, or run the build with PHP_CONFIG=/path/to/php-config.

PHP cannot load the shared object

Confirm the shared object path is correct and that the runtime PHP binary matches the PHP ABI used for compilation.

Clang or libclang is missing

Install Clang and libclang, or set LIBCLANG_PATH to the directory containing the libclang library.

You only want to test Rust parser kernels

Run cd extensions/native-apis && cargo test. This path does not require PHP development headers.