Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Global State Laravel Package

sebastian/global-state

sebastian/global-state snapshots and restores PHP global state (globals, superglobals, ini settings, etc.), extracted from PHPUnit as a standalone component. Useful for test isolation and detecting side effects by capturing state before and after code runs.

View on GitHub
Deep Wiki
Context7

Getting Started

Install as a dev dependency:

composer require --dev sebastian/global-state

First use case: Isolate tests modifying global state (e.g., $_ENV, $_SERVER, or static properties). Initialize in setUp():

use SebastianBergmann\GlobalState\Snapshot;

public function setUp(): void
{
    $this->snapshot = Snapshot::snapshot();
}

Restore in tearDown():

public function tearDown(): void
{
    $this->snapshot->restore();
}

Where to look first:


Implementation Patterns

Test Isolation

Use snapshots to reset global state between tests, especially for:

  • Superglobals: $_GET, $_POST, $_ENV (avoid $_SESSION/$_COOKIE by default).
  • Static properties: Explicitly include classes via Snapshot::snapshot(['staticProperties' => [App\Class::class]]).
  • INI settings: Capture with Snapshot::snapshot(['iniSettings' => ['error_reporting']]).

Example: Selective snapshot for $_ENV

public function testEnvironmentVariables()
{
    $snapshot = Snapshot::snapshot(['superGlobals' => ['$_ENV']]);
    $_ENV['TEST_VAR'] = 'value';
    $this->assertEquals('value', $_ENV['TEST_VAR']);
    $snapshot->restore(); // $_ENV['TEST_VAR'] is unset
}

Integration with Laravel

Leverage in:

  1. Custom Test Cases: Extend PHPUnit\Framework\TestCase for legacy projects.
  2. CLI Scripts: Reset state between command executions (e.g., Artisan commands modifying $_SERVER).
  3. Swoole/Long-Running Processes: Restore state between requests to avoid pollution.

Example: Artisan Command Testing

public function testCommandModifiesGlobals()
{
    $snapshot = Snapshot::snapshot(['superGlobals' => ['$_SERVER']]);
    $this->artisan('command:test')->assertExitCode(0);
    $snapshot->restore(); // Reset $_SERVER after command
}

Performance Optimization

  • Avoid full snapshots: Specify only needed state (e.g., ['globals' => ['$_ENV']]).
  • Cache snapshots: Reuse snapshots for identical test groups (e.g., beforeEach in Pest).

Gotchas and Tips

Pitfalls

  1. PHP Version Lock-In:

    • v9.x requires PHP 8.1–8.3; v8.x drops PHP 8.2.
    • Fix: Pin to ^8.0 for Laravel’s PHP 8.0–8.2 support:
      "sebastian/global-state": "^8.0"
      
  2. Superglobal Quirks:

    • $_SESSION/$_COOKIE are not snapshotted by default (risk of race conditions).
    • Workaround: Use snapshotSuperGlobalArray() only if you control session storage (e.g., in-memory for tests).
  3. Static Properties:

    • Only declared statics are captured. Dynamic properties (e.g., $obj->dynamic = 'x') are ignored.
    • Tip: Use ReflectionClass to verify coverage.
  4. Performance Spikes:

    • Large $GLOBALS or complex objects slow snapshots.
    • Mitigation: Profile with Snapshot::snapshot(['globals' => []]) to exclude unnecessary state.

Debugging

  • Verify Restores: Add assertions post-restore:
    $snapshot->restore();
    $this->assertNull($_ENV['TEST_VAR'] ?? null);
    
  • Check for Leaks: Use Xdebug to trace unexpected global modifications.

Extension Points

  1. Custom State Providers: Implement SebastianBergmann\GlobalState\StateProviderInterface to snapshot non-standard state (e.g., Laravel’s app container):

    class AppStateProvider implements StateProviderInterface
    {
        public function getState(): array { return ['app' => app()->bindings()]; }
        public function restoreState(array $state): void { /* ... */ }
    }
    
  2. PHPUnit Listeners: Hook into testStarted/testFinished to auto-manage snapshots:

    use SebastianBergmann\GlobalState\Snapshot;
    
    class GlobalStateListener implements TestListener
    {
        public function testStarted(Test $test): void
        {
            $test->snapshot = Snapshot::snapshot();
        }
        public function testFinished(Test $test): void
        {
            $test->snapshot->restore();
        }
    }
    

Laravel-Specific Tips

  • Avoid in Production: This package is test-only; never use it in runtime code.
  • Prefer DI: For application logic, replace global state with dependency-injected services (e.g., Config, Cache).
  • Pest Integration: Use beforeEach/afterEach for snapshot management:
    beforeEach(function () {
        $this->snapshot = Snapshot::snapshot(['superGlobals' => ['$_ENV']]);
    });
    afterEach(function () {
        $this->snapshot->restore();
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope