@@ -179,18 +179,21 @@ behavior a single worker would have produced sequentially.
179179
180180The router is committed at ` tools/local-env/router.php ` alongside
181181` envlite.php ` ; it is not installed into the repo, the manifest does
182- not track it, and ` clean ` does not remove it. It has no inputs (the
183- port is a ` php -S ` argument, not baked into the file) and no
184- user-tunable knobs.
185-
186- The router resolves the repo's ` src/ ` via
187- ` dirname(__DIR__, 2) . '/src' ` , returns ` false ` for files that exist
188- on disk so ` php -S ` serves them directly, and otherwise routes to
189- ` src/index.php ` . WordPress's index.php → wp-blog-header.php →
190- wp-load.php → wp-settings.php chain handles the rest, including
191- ` wp-admin/install.php ` on first hit and pretty-permalink fallback
192- once installed. The port is consumed only when ` serve ` runs, never
193- at ` init ` time.
182+ not track it, and ` clean ` does not remove it. Its only request-time
183+ inputs are the request URI and ` $_SERVER['DOCUMENT_ROOT'] ` — the
184+ absolute path PHP's built-in server resolved from its ` -t ` argument
185+ — so the router file's own filesystem location is deliberately
186+ irrelevant. The port is a ` php -S ` argument, never baked into the
187+ file, and the router has no user-tunable knobs.
188+
189+ The router uses ` $_SERVER['DOCUMENT_ROOT'] ` to locate both static
190+ files and the front controller: it returns ` false ` for paths that
191+ exist on disk under the docroot so ` php -S ` serves them directly,
192+ and otherwise ` require ` s ` <DOCUMENT_ROOT>/index.php ` . WordPress's
193+ index.php → wp-blog-header.php → wp-load.php → wp-settings.php
194+ chain handles the rest, including ` wp-admin/install.php ` on first
195+ hit and pretty-permalink fallback once installed. The port is
196+ consumed only when ` serve ` runs, never at ` init ` time.
194197
195198** Bind failure.** envlite's pre-flight ` port_is_free ` probe (in both
196199` serve ` and ` up ` ) detects an already-bound port and exits 1 with a
@@ -1097,6 +1100,23 @@ explicit user assent. Users who want a fully clean slate run
10971100 because the rationale for tracking the live DB — possible
10981101 user-authored content — does not apply to a file phpunit drops
10991102 every run.
1103+ 16 . ** Router resolves paths via ` $_SERVER['DOCUMENT_ROOT'] ` , not
1104+ from ` __DIR__ ` .** ` php -S -t <dir> ` populates ` DOCUMENT_ROOT `
1105+ with the absolute resolution of ` -t ` ; ` envlite_run_dev_server `
1106+ chdirs into the target repo and passes ` -t src ` before launch,
1107+ so ` $_SERVER['DOCUMENT_ROOT'] ` always equals ` <target-repo>/src `
1108+ at request time. Resolving from there decouples the router's
1109+ * resolution behavior* from the router file's * filesystem
1110+ location* : the router file can be loaded from a sibling envlite
1111+ checkout, a vendored copy, or a symlink without serving the
1112+ wrong repo. An earlier draft used ` dirname(__DIR__, 2) . '/src' `
1113+ and silently broke this property — invoking envlite from one
1114+ worktree against a different worktree's repo loaded the
1115+ invoker's ` wp-config.php ` (with its ` WP_HOME ` /` WP_SITEURL ` ) and
1116+ triggered a canonical-URL 301 to the wrong port.
1117+ ` tools/local-env/tests/test_router.php ` is the regression test;
1118+ it boots ` php -S ` against a fixture docroot wholly outside the
1119+ router file's tree.
11001120
11011121---
11021122
0 commit comments