Problem
#50 ✅ shipped VM CGI via bin/cgi.php + lib/Web/CgiDriver.php + CgiDriverTest (#656). Production deploys compile with phpc build / phpc deploy and need the same CGI env → Status + headers + body contract for a native binary, not php bin/cgi.php.
phpc serve --aot is dev-only; nginx cgi blocks expect an executable that reads env/stdin per request.
Goal
Documented production path:
phpc deploy examples/003-MiniWebApp -o /var/www/miniwebapp
# nginx: fastcgi_pass /var/www/miniwebapp/cgi-wrapper (or Action cgi-script)
export PHPC_DEPLOY_ROOT=/var/www/miniwebapp
./cgi-wrapper # sets env, execs bin/app, forwards stdin body
Wrapper sets PHPC_DEPLOY_ROOT, refreshes superglobals (#201 ✅), runs compiled entry (phpc.json "binary"), emits CGI response.
Implementation hints
| Piece |
Notes |
| Shim |
Small C or PHP launcher: read CONTENT_LENGTH, stdin → REQUEST_BODY, execve AOT binary |
| Entry |
Reuse lib/AOT/runtime/superglobals_refresh.c init already linked in web AOT binaries |
| CLI |
Optional phpc cgi subcommand wrapping shim + manifest binary path |
| Docs |
Section in #635 / #445 with nginx ScriptAlias example |
| Tests |
Extend CgiDriverTest phase B: skip until #568 + #612 dist layout green |
Acceptance criteria
phpc build -o /tmp/app examples/001-SimpleWeb/example.php
REQUEST_METHOD=GET QUERY_STRING=name=AotCgi /tmp/cgi-wrapper /tmp/app
Stdout contains Status: 200 and AotCgi in body (VM parity test exists; AOT case unskipped when link works).
Verification
docker run --rm -v "$(pwd):/compiler" -w /compiler php-compiler:22.04-dev \
./script/ci-local.sh --filter CgiDriverTest
Local/Docker only — not GitHub Actions.
Dependencies
Links
Problem
#50 ✅ shipped VM CGI via
bin/cgi.php+lib/Web/CgiDriver.php+CgiDriverTest(#656). Production deploys compile withphpc build/phpc deployand need the same CGI env → Status + headers + body contract for a native binary, notphp bin/cgi.php.phpc serve --aotis dev-only; nginxcgiblocks expect an executable that reads env/stdin per request.Goal
Documented production path:
Wrapper sets
PHPC_DEPLOY_ROOT, refreshes superglobals (#201 ✅), runs compiled entry (phpc.json"binary"), emits CGI response.Implementation hints
CONTENT_LENGTH, stdin →REQUEST_BODY,execveAOT binarylib/AOT/runtime/superglobals_refresh.cinit already linked in web AOT binariesphpc cgisubcommand wrapping shim + manifestbinarypathScriptAliasexampleCgiDriverTestphase B: skip until #568 + #612 dist layout greenAcceptance criteria
Stdout contains
Status: 200andAotCgiin body (VM parity test exists; AOT case unskipped when link works).Verification
docker run --rm -v "$(pwd):/compiler" -w /compiler php-compiler:22.04-dev \ ./script/ci-local.sh --filter CgiDriverTestLocal/Docker only — not GitHub Actions.
Dependencies
phpc deployPHPC_DEPLOY_ROOTdist E2ELinks
bin/cgi.php,lib/Web/CgiDriver.php