Skip to content

PHP: add libzip + --with-zip so ZipArchive works #550

@mho22

Description

@mho22

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:

  1. 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.tomlscript_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.
  2. 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.
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions