From aa2124fe5d0c96078c034a6e4044b7e81acdf692 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 16 Aug 2026 14:18:41 +0900 Subject: feat(php-rpc): replay Rust-side env writes into the PHP worker The worker is a long-lived child holding the environment it was handed at spawn, so `@putenv`, the bin dir the event dispatcher prepends to PATH, and COMPOSER_DEV_MODE never reached the PHP code running in it. The shim now journals every write to the three storages PHP exposes, and the outermost rpc_call replays the entries the worker has not seen yet through __shirabe_sync_env. Replaying the writes rather than pushing a whole snapshot keeps the worker's own $_SERVER entries intact. Co-Authored-By: Claude Opus 5 (1M context) --- docs/dev/env-vars-porting.md | 19 ++++++++++++------- docs/dev/php-rpc.md | 4 ++++ 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'docs') diff --git a/docs/dev/env-vars-porting.md b/docs/dev/env-vars-porting.md index fbee8703..af4c947a 100644 --- a/docs/dev/env-vars-porting.md +++ b/docs/dev/env-vars-porting.md @@ -33,12 +33,17 @@ each call site. | `$_ENV` | `PHP_ENV` | | `$_SERVER` | `PHP_SERVER` | -## TODOs +## Reaching the PHP runtime + +The PHP worker is a separate, long-lived process (`docs/dev/php-rpc.md`): it holds the environment +it was handed at spawn, so a later write on the Rust side would be invisible to the PHP code +running in it. Every write to one of the three storages is therefore recorded in an ordered journal +(`env_mutations_since`), and `shirabe-php-rpc` replays the entries the worker has not seen yet — +through `__shirabe_sync_env`, which writes each entry to the storage it names — before the next call +crosses the boundary. Replaying the writes rather than pushing a whole snapshot is what keeps the +worker's own `$_SERVER` entries (`argv`, `SCRIPT_NAME`, ...) intact. -The current implementation only models the Rust side. Two things remain unimplemented: +## TODOs -* Propagating `$_ENV`/`$_SERVER` into the real PHP runtime. When Shirabe hands control to PHP - (for the plugin API), the PHP side needs to see the same `$_ENV`/`$_SERVER` snapshot Shirabe - holds. This is marked `TODO(php-runtime)` in `env.rs` and is not yet wired up. -* Reflecting PHP-side mutations of `$_ENV`/`$_SERVER` back into Shirabe. How to handle the case - where PHP code rewrites `$_ENV` or `$_SERVER` is still TBD. +Reflecting PHP-side mutations of `$_ENV`/`$_SERVER` back into Shirabe is unimplemented. How to +handle the case where PHP code rewrites `$_ENV` or `$_SERVER` is still TBD. diff --git a/docs/dev/php-rpc.md b/docs/dev/php-rpc.md index f91b8e54..eb93db19 100644 --- a/docs/dev/php-rpc.md +++ b/docs/dev/php-rpc.md @@ -165,6 +165,10 @@ Notable internal helpers: - `__shirabe_settle_promise` — the inverse: drains a promise a plugin returned to Rust. React settles synchronously, so an already-settled promise yields its value here (a rejection is re-thrown as the Throw reply); one that is still pending is an explicit error. +- `__shirabe_sync_env` — replays the environment writes the Rust side made after the worker was + spawned into the storage each one names (`putenv()`, `$_ENV`, `$_SERVER`); see + [docs/dev/env-vars-porting.md](./env-vars-porting.md). The outermost `rpc_call` of a session + issues it whenever the journal has moved on. - `__shirabe_get_property` — for testing only: reads a public property of a P-table entity. - `__shirabe_oracle_roundtrip` — codec oracle support for tests. - `__shirabe_console_application_boot` — builds the worker-side `Composer\Console\Application` -- cgit v1.3.1-4-g156e