Skip to content

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

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

    Fields

    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