Stacks¶
A stack is a PHP version, a set of extensions, what to embed, which targets to build and where,
with a name. The builds of this repository are declared in stacks.php, the page of each example in
its stack.php, and castor builds them with one command. castor only
runs docker buildx bake for you, the Dockerfile is what knows how to compile PHP: nobody needs
castor to use this repository. castor is a single binary, installed with
curl "https://castor.jolicode.com/install" | bash.
<?php
use PhpWasm\Stack;
use PhpWasm\Target;
$php85 = Stack::named('php-8.5')
->php('8.5.12')
->extensions('calendar', 'ctype', 'dom', 'mbstring', 'simplexml', 'xml', 'xmlreader', 'xmlwriter')
->targets(Target::Web, Target::Node);
return [
$php85,
// Everything from php-8.5, and two more extensions
$php85->renamed('php-8.5-bcmath')->extensions('bcmath', 'tokenizer'),
];
A stack never changes: each method returns a new one, so a stack is derived from another one with
renamed(). extensions() adds to the extensions the stack already has, the other methods replace
what it has. Each method sets a build argument:
| Method | Build argument |
|---|---|
php('8.5.12') |
PHP_VERSION |
extensions('intl') |
EXTENSIONS |
targets(Target::Web) |
TARGETS |
memory('256mb') |
MEMORY |
icuData(IcuData::None) |
ICU_DATA |
opcache(Opcache::Precompiled) |
OPCACHE |
embed('build/dist', at: '/app') |
EMBED_AT, and the embed context |
warmup('bin/console', 'cache:warmup') |
WARMUP |
embed() is relative to the root of the project, the directory of castor.php, and the directory
shows up at /<its name> in the WASM filesystem, unless embed() is told where. outputDir()
writes the files somewhere else than build/<stack>/, also relative to the root of the project.
To build your own stacks with this repository as it is, declare them in a stacks.override.php file
next to stacks.php, with the same format (git ignores it). Its stacks are added to the ones of
stacks.php, or replace the ones that have the same name.
The tasks¶
Unless a stack says otherwise, everything is built in build/<stack>/:
castor wasm:stacks # lists the stacks
castor wasm:build # builds php-8.5
castor wasm:build php-8.5-intl # builds another one
castor wasm:build --all # builds all of them, in one buildx invocation (with the overrides below)
castor wasm:check # builds them all, and checks them
castor wasm:sizes # compares the size of the .wasm files with php-8.5
castor wasm:run my-script.php # runs a file, in php-8.5
castor wasm:run -r 'echo PHP_VERSION;' --stack php-8.3
castor wasm:serve # lists the examples
castor wasm:serve playground # builds the page of examples/playground/, and serves it
castor wasm:serve playground --php 8.3.35 # the same page, on PHP 8.3
Anything in a stack can be overridden from the command line, so there is no need to declare a stack to try something:
castor wasm:build --php 8.3.35 # php-8.5, on PHP 8.3
castor wasm:build php-8.3 --target node # only the node target
castor wasm:build --with tokenizer --with bcmath # php-8.5, and two more extensions
castor wasm:build --memory 256mb --embed my-app # more memory, another directory to embed
castor wasm:build php-8.5-intl --icu-data none # intl, without ICU's data
castor wasm:build --embed my-app --opcache precompiled # opcache compiles what is embedded when it is built
castor wasm:build --print # only shows the bake file
What is built with overrides goes to the directory of the stack (build/php-8.5/,
build/php-8.3/), in place of what was there.
castor wasm:run runs a file, or some code, in a stack, and offers to build it when it is not built
yet.
The checks¶
castor wasm:check is what tells that a stack works: once built, it runs every build of each stack
in node, the one for the web too, and checks that PHP_VERSION is the one that was asked for, that
extension_loaded() is true for every extension that was asked for, and that the JavaScript API
works (tests/api.test.mjs). It does not run what the stack embeds.
stacks.php has the builds of this repository, that castor wasm:check checks with the stacks of
the examples, in CI too:
| Stack | What it is |
|---|---|
php-8.5 |
PHP 8.5, with the default extensions: what docker buildx bake builds too. |
php-8.4, php-8.3 |
The same thing, on older PHP versions. |
php-8.5-intl |
Adds intl, with ICU's data (see intl). |
php-8.5-opcache-runtime, php-8.5-opcache-precompiled |
opcache keeps what it compiles in files (see opcache). |