Emit a dispatch-free runtime.prepend.php from the php-builtin applier#278
Emit a dispatch-free runtime.prepend.php from the php-builtin applier#278epeicher wants to merge 1 commit into
runtime.prepend.php from the php-builtin applier#278Conversation
The php-builtin applier wrote a single runtime.php that concatenates the routing-free base layers (constants, SQLite $wpdb shim, uploads proxy) with a CLI-server routing tail that dispatches WordPress (require index.php). That file is correct as a standalone `php -S` router, but when a host owns its own router and injects runtime.php via auto_prepend_file, the tail dispatches WordPress during the prepend phase, bypassing the SQLite shim and falling back to MySQL — "Error establishing a database connection". Emit runtime.prepend.php alongside runtime.php: the same base layers with no routing tail, purpose-built for hosts that own request dispatch (e.g. Studio's native php -S router). runtime.php and start.sh are unchanged, so standalone usage is unaffected. This mirrors the existing nginx-fpm applier, which already consumes the base-only output via auto_prepend_file. Also fix the generate_cli_server_routing() docblock, which falsely claimed the routing tail was guarded by a php_sapi_name check — it runs unconditionally, and php_sapi_name() is 'cli-server' in both modes so it could not distinguish them anyway.
Pull pipeline performance —
|
| Stage | PR | trunk | Δ | Status | Details |
|---|---|---|---|---|---|
playground-sqlite-db-pull |
9.36 s | 9.81 s | ⚪ -451 ms (-4.6%) | ✓ | condition=db-pull in PHP.wasm runtime=php.wasm 8.3 wp_mysql_parser=enabled mode=lexer native_lexer=verified native_token_stream=WP_MySQL_Native_Token_Stream native_token_count=18 native_parser=selected trunk: condition=db-pull in PHP.wasm runtime=php.wasm 8.3 wp_mysql_parser=enabled mode=lexer native_lexer=verified native_token_stream=WP_MySQL_Native_Token_Stream native_token_count=18 native_parser=selected |
playground-sqlite-db-apply |
3.56 s | 3.64 s | ⚪ -88 ms (-2.4%) | ✓ | condition=db-apply to SQLite in PHP.wasm runtime=php.wasm 8.3 wp_mysql_parser=enabled mode=parser native_lexer=verified native_token_stream=WP_MySQL_Native_Token_Stream native_token_count=18 native_parser=verified native_ast=WP_MySQL_Native_Parser_Node sqlite_driver_parser=verified trunk: condition=db-apply to SQLite in PHP.wasm runtime=php.wasm 8.3 wp_mysql_parser=enabled mode=parser native_lexer=verified native_token_stream=WP_MySQL_Native_Token_Stream native_token_count=18 native_parser=verified native_ast=WP_MySQL_Native_Parser_Node sqlite_driver_parser=verified |
| Total | 12.92 s | 13.46 s | ⚪ -540 ms (-4.0%) |
Numbers carry runner noise; treat single-run deltas as directional, not authoritative.
📈 Trunk performance history — commit-by-commit timeline.
|
Closing this PR as not required, the changes are already in Reprint, the solution was just to use The reason this was not identified before: I had the answer in my hands and walked past it. My analysis explicitly called out the Three things led me there:
That's a real miss, not a toolchain issue: the cheaper hypothesis ("change one argument") was reachable from my own findings, and I should have surfaced it as option 0 before recommending a reprint change. |
What it does
The
php-builtinruntime applier now writes a second artifact,runtime.prepend.php, alongsideruntime.php. It contains the same environment setup (DB constants, the lazy SQLite$wpdbproxy, the uploads proxy) without the CLI-server routing tail that dispatches WordPress.runtime.phpandstart.share unchanged, so standalonephp -Susage is unaffected.Rationale
runtime.phpglues together two unrelated jobs: (1) environment setup and (2) a request router thatrequires WordPress. Both are correct when reprint owns the server (start.sh→php -S … runtime.php).But WordPress Studio's native-PHP
pull-reprintruns its ownphp -S … router.phpworkers and injects reprint's environment via-d auto_prepend_file=runtime.php.auto_prepend_fileis a per-request bootstrap slot, not a dispatch slot — so the routing tail dispatches WordPress during the prepend phase, the SQLite$wpdbshim no longer governs the request that actually serves the page, WordPress falls back to the real MySQLwpdb, and every pulled site dies at startup with "Error establishing a database connection" (the worker exits 1).Studio currently works around this by string-stripping the router tail off
runtime.phpdownstream. This change supplies the clean artifact instead. It mirrors the existingnginx-fpmapplier, which already ships a routing-freeruntime.phpconsumed viaauto_prepend_file.Implementation
PhpBuiltinApplier::apply()computes the routing-free base once, then writesruntime.php= base + routing tail (unchanged) andruntime.prepend.php= base only.generate_cli_server_routing()docblock, which falsely claimed the routing tail was guarded by aphp_sapi_namecheck. It runs unconditionally — andphp_sapi_name()iscli-serverin both modes, so it could not distinguish them anyway.New test
PhpBuiltinPrependArtifactTestcovers:runtime.phpkeeps the routing tail;runtime.prepend.phpomits it but is the exact base prefix ofruntime.phpphp -l-cleanphp -d auto_prepend_file=runtime.prepend.php <probe>resolves$GLOBALS['wpdb']to the SQLite loader with no dispatch and no DB error — exactly Studio's injection pathTesting instructions
TBD