Summary
The Kandelo PHP package (packages/registry/php/) builds PHP 8.3.15 without the zip extension, so new ZipArchive is unavailable at runtime:
Fatal error: Uncaught Error: Class "ZipArchive" not found in Command line code:8
Adding a libzip package under packages/registry/libzip/, resolving it from build-php.sh, and passing --with-zip to PHP's ./configure would close the gap.
Why this matters
The headline integration target on the roadmap (#382, Layer 0) is WordPress Playground with --experimental-posix-kernel. Playground's installPlugin / installTheme / unzip Blueprint steps all funnel through one helper, unzipFile() in @wp-playground/common, which calls:
$zip = new ZipArchive;
$res = $zip->open($zipPath);
$zip->extractTo($extractTo, $filename);
against the fetched wp.org plugin/theme zip. Without ZipArchive every one of those steps fails. The classic Emscripten-based php-wasm build configures --with-zip for exactly this reason — see packages/php-wasm/compile/php/Dockerfile in WordPress/wordpress-playground. Reaching feature parity between the two PHP runtimes is what lets the Playground PoC PRs (#3634 CLI, #3635 Web) ship a working installPlugin.
Reproducer
Against any current Kandelo PHP CLI binary:
echo '<?php var_dump(class_exists("ZipArchive"));' | <run-php-via-kernel> -r -
# Expected: bool(true)
# Actual: bool(false)
Or, more directly, attempting to extract any DEFLATE zip:
echo '<?php $z = new ZipArchive; var_dump($z->open("/tmp/x.zip"));' | <run-php-via-kernel> -r -
# Fatal error: Uncaught Error: Class "ZipArchive" not found
Root cause
packages/registry/php/build-php.sh resolves four C-library deps (zlib, sqlite, openssl, libxml2) and configures PHP with their corresponding --with-* flags, but does not include libzip:
$ grep -i 'zip\|libzip' packages/registry/php/build-php.sh
$ # (no output)
packages/registry/ has compression utilities (zip, unzip, gzip, bzip2, xz, zstd — landed in #222) but those are standalone CLI binaries, not a linkable libzip for PHP's ext/zip. PHP 8.3 requires an external libzip ≥ 0.11; the in-tree bundled-libzip path is upstream-removed.
Proposed fix
Three small pieces:
- New package
packages/registry/libzip/ with the usual recipe shape (mirror packages/registry/zlib/ since libzip's autoconf flow is comparable):
package.toml — name, version (e.g. libzip 1.10.1), source URL, [build].script_path.
build.toml — script_path, repo_url, commit, revision = 1, [binary] index_url.
build-libzip.sh — sources sdk/activate.sh, resolves zlib, cross-compiles with wasm32posix-configure --disable-shared --enable-static --with-zlib=..., installs into $INSTALL_DIR.
- Wire it into PHP: in
packages/registry/php/build-php.sh, add a LIBZIP_PREFIX="$(resolve_dep libzip)" block alongside the existing resolves, append -I$LIBZIP_PREFIX/include / -L$LIBZIP_PREFIX/lib to DEP_CPPFLAGS / DEP_LDFLAGS, and add --with-zip to the wasm32posix-configure invocation.
- Bump
packages/registry/php/build.toml revision from 2 to 3 so the content-addressed cache rebuilds rather than serving the pre-zip archive.
No ABI_VERSION bump required (this is an ext/zip capability change, not a kernel ABI change).
Acceptance
new ZipArchive resolves; $zip->open() / $zip->extractTo() work against a vanilla wp.org plugin zip (e.g. https://downloads.wordpress.org/plugin/hello-dolly.latest-stable.zip, 1887 bytes, plain DEFLATE).
- The published
binaries-abi-v<N> index entry for php on wasm32 references the new revision.
- WordPress Playground's
installPlugin blueprint step succeeds in kernel mode.
References
Summary
The Kandelo PHP package (
packages/registry/php/) builds PHP 8.3.15 without thezipextension, sonew ZipArchiveis unavailable at runtime:Adding a
libzippackage underpackages/registry/libzip/, resolving it frombuild-php.sh, and passing--with-zipto PHP's./configurewould close the gap.Why this matters
The headline integration target on the roadmap (#382, Layer 0) is WordPress Playground with
--experimental-posix-kernel. Playground'sinstallPlugin/installTheme/unzipBlueprint steps all funnel through one helper,unzipFile()in@wp-playground/common, which calls:against the fetched wp.org plugin/theme zip. Without
ZipArchiveevery one of those steps fails. The classic Emscripten-based php-wasm build configures--with-zipfor exactly this reason — seepackages/php-wasm/compile/php/DockerfileinWordPress/wordpress-playground. Reaching feature parity between the two PHP runtimes is what lets the Playground PoC PRs (#3634 CLI, #3635 Web) ship a workinginstallPlugin.Reproducer
Against any current Kandelo PHP CLI binary:
Or, more directly, attempting to extract any DEFLATE zip:
Root cause
packages/registry/php/build-php.shresolves four C-library deps (zlib,sqlite,openssl,libxml2) and configures PHP with their corresponding--with-*flags, but does not includelibzip:packages/registry/has compression utilities (zip,unzip,gzip,bzip2,xz,zstd— landed in #222) but those are standalone CLI binaries, not a linkablelibzipfor PHP'sext/zip. PHP 8.3 requires an external libzip ≥ 0.11; the in-tree bundled-libzip path is upstream-removed.Proposed fix
Three small pieces:
packages/registry/libzip/with the usual recipe shape (mirrorpackages/registry/zlib/since libzip's autoconf flow is comparable):package.toml— name, version (e.g. libzip 1.10.1), source URL,[build].script_path.build.toml—script_path,repo_url,commit,revision = 1,[binary] index_url.build-libzip.sh— sourcessdk/activate.sh, resolveszlib, cross-compiles withwasm32posix-configure --disable-shared --enable-static --with-zlib=..., installs into$INSTALL_DIR.packages/registry/php/build-php.sh, add aLIBZIP_PREFIX="$(resolve_dep libzip)"block alongside the existing resolves, append-I$LIBZIP_PREFIX/include/-L$LIBZIP_PREFIX/libtoDEP_CPPFLAGS/DEP_LDFLAGS, and add--with-zipto thewasm32posix-configureinvocation.packages/registry/php/build.tomlrevision from2to3so the content-addressed cache rebuilds rather than serving the pre-zip archive.No
ABI_VERSIONbump required (this is anext/zipcapability change, not a kernel ABI change).Acceptance
new ZipArchiveresolves;$zip->open()/$zip->extractTo()work against a vanilla wp.org plugin zip (e.g.https://downloads.wordpress.org/plugin/hello-dolly.latest-stable.zip, 1887 bytes, plain DEFLATE).binaries-abi-v<N>index entry for php onwasm32references the new revision.installPluginblueprint step succeeds in kernel mode.References
--with-zip):packages/php-wasm/compile/php/Dockerfilepackages/registry/php/build-php.sh