sebastian/global-state
Snapshot and restore PHP global state with sebastian/global-state, the standalone component extracted from PHPUnit. Capture globals, superglobals, static properties, and constants for reliable test isolation.
Build vs. buy — already resolved, for free. This is not a procurement decision. sebastian/global-state is a hard dependency of PHPUnit, which every Laravel project already carries in require-dev. BSD-3-Clause, zero new license review, no vendor relationship, no incremental supply-chain surface. The only live decision is whether to declare it directly and wrap it, or leave it as invisible plumbing. Default position: leave it invisible until a measured problem appears.
Sprint capacity allocation for test reliability. If the backlog carries items like "reduce flaky tests" or "clean up test isolation," this package closes out the specific category caused by superglobal and static-property leakage without commissioning bespoke setUp/tearDown reset helpers. That is a clean "don't build this" line item for roadmap planning — you are choosing to consume a proven primitive instead of funding one.
Roadmap gating on PHP upgrades. The support matrix is a hard constraint, not a footnote: v9 drops PHP 8.3, v8.x targets 8.0–8.2, v7.x covers 8.1–8.3. Because it rides along with PHPUnit majors, its support window becomes a de facto constraint on the platform's PHP upgrade timeline. That belongs in the upgrade RFC and the platform dependency register, not the feature backlog.
Feature scoping for long-running processes. If the roadmap includes Laravel Octane, Swoole, or stateful queue workers, snapshot/restore semantics inform how you design per-request state hygiene — i.e., whether to lean on this or build explicit reset contracts into your own services. The honest answer for production code is almost always the latter.
Test-infrastructure sizing. As a dev-only utility, the decision it informs is how much ownership to take over test harness code — specifically whether test isolation is a shared base-class concern (one wrapper, centrally maintained, named owner) or everyone's individual problem. That is a resourcing question a PM can actually act on and staff.
Use cases worth naming explicitly, so scope stays tight: legacy suites with order-dependent failures; internal packages with custom or non-PHPUnit harnesses; CLI scripts and workers needing deterministic state resets between iterations. Everything else is a non-use-case, and naming them prevents scope creep into "we'll add snapshotting everywhere."
Adopt direct usage when:
$GLOBALS, $_ENV, $_SERVER, $_SESSION, or static properties in ways RefreshDatabase, per-test application instances, container rebinding, and fake() helpers do not cover.--order-by=random) and repeat-run instrumentation are the evidence you need before spending a sprint.TestCase or internal test-harness package where one wrapper can serve many suites — that is where the leverage is, and where a single owner keeps knowledge from concentrating in one person.['globals' => ['$_ENV']]) rather than full captures, because suite runtime and memory are already a concern.Look elsewhere — or simply don't adopt — when:
RefreshDatabase, Facade::clearResolvedInstances(), container rebinding, and per-test app boots handle the leakage categories feature tests actually hit.tests/. Restoring $_ENV/$_SERVER/$_SESSION in runtime code is a stability and security concern — a stop-work signal, not an optimization.Gate the decision on five questions: Do we have a measured flake rate or are we pre-optimizing? What version does Composer resolve for us today, and what pin does phpunit/phpunit impose? Are we running parallel tests where restore semantics become a correctness issue? Which leakage classes does our suite exhibit that Laravel isolation misses? And who owns test infrastructure?
One line: A free, test-only utility that removes a class of flaky-test toil — adopt it deliberately where leakage is measured, and otherwise leave it where it already sits, inside PHPUnit.
For executives: This is not a purchase, a platform bet, or a vendor relationship. It is a component of PHPUnit that we already have. The decision on the table is small and bounded: whether to spend roughly half a day of one engineer's time plus a one-page internal doc to wrap it, if and only if we have evidence that global-state leakage is causing flaky tests. The cost of saying no is zero; the cost of saying yes is a recurring line item in every PHP and PHPUnit upgrade — because this package's support window moves in lockstep with PHPUnit majors and therefore becomes a quiet constraint on our platform upgrade train. Recommendation: fund the measurement step (a flake taxonomy and a CI gate), not the adoption. That produces durable value regardless of outcome.
For engineering: Mechanics are trivial — composer require --dev, a ~50-line GlobalStateIsolation trait using Snapshot::snapshot() and Restorer with try/finally rather than relying on tearDown ordering. Use selective snapshots by default; full captures scale with suite size × $GLOBALS size × object-graph complexity and retain references in long-running suites. Document the default exclusions ($_SESSION, $_COOKIE) and pin the resolved version in the dependency register. If you run Paratest, treat restore semantics as unproven until a repeat-run soak says otherwise — full-snapshot restore mutates process-wide state. And keep it out of the production autoload path; a test-suite workaround is not a remediation plan for global-state design problems in application code.
For the roadmap: Two artifacts come out of this either way — a flake taxonomy with a baseline rate, and a dependency-register entry tying this package's version to our PHP support window. Sequence it inside one sprint and one squad: spike one high-flake suite, measure before/after runtime and flake rate, wrap it, roll to the shared base case behind a documented exclusion list. Kill criterion: if no confirmed leakage-attributable failures exist, close it and consume it transitively. That is the expected outcome and a good one.
How can I help you explore Laravel packages today?