PHP code example of jonbaldie / phpstan-extension-accessing-globals

1. Go to this page and download the library: Download jonbaldie/phpstan-extension-accessing-globals library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

jonbaldie / phpstan-extension-accessing-globals example snippets




// Root-level variables that will be accessed globally
$db = null;
$config = ['host' => 'localhost'];

// ❌ BAD: neverAccessGlobals
function connectDatabase(): void {
    global $db, $config;  // Accessing global variables - hidden dependency!
    // ...
}

// ❌ BAD: neverModifyGlobals
function setCache(): void {
    $GLOBALS['cache'] = new Cache();  // Modifying via $GLOBALS array
}

// ❌ BAD: neverModifyGloballyDeclaredVariables
function initDb(): void {
    global $db;           // Accessing global (first error)
    $db = new PDO(...);   // Modifying it (second error)
}

// ❌ BAD: neverAccessSuperGlobalsInNestedScope
function getUserId(): int {
    return $_SESSION['user_id'];  // Accessing superglobal in function - hidden dependency!
}

// ❌ BAD: neverModifySuperGlobalsInNestedScope
function login(User $user): void {
    $_SESSION['user_id'] = $user->id;  // Modifying superglobal in function
}

// ✅ GOOD: Root scope superglobal access is allowed
$userId = $_SESSION['user_id'] ?? null;
$requestId = $_GET['id'] ?? null;

// ✅ GOOD: Pass dependencies explicitly
function connectDatabase(array $config): PDO {
    return new PDO($config['host'], $config['user'], $config['pass']);
}

function getUserId(array $session): int {
    return $session['user_id'];
}

function login(User $user): array {
    return ['user_id' => $user->id];  // Return new state instead of mutating
}



// ❌ BAD: Even root-scope superglobal access is forbidden
$userId = $_SESSION['user_id'];  // neverAccessSuperGlobals
$_SESSION['last_seen'] = time();  // neverModifySuperGlobals

// ✅ GOOD: Wrap superglobals in a service/class at entry point, inject it
class Request {
    public function __construct(private array $query) {}
    public function get(string $key): mixed { return $this->query[$key] ?? null; }
}

$request = new Request($_GET);  // Wrap once at entry point
processRequest($request);        // Pass it explicitly



define('API_KEY', 'secret123');

class Config {
    public static $timeout = 30;
    public const MAX_RETRIES = 3;
}

// ❌ BAD: ForbidUsingGlobalConstants
function callApi(): void {
    $key = API_KEY;  // Hidden dependency on global constant
}

// ❌ BAD: ForbidUsingGlobalConstants (via constant())
function readMode(): string {
    return constant('APP_MODE');  // Same hidden dependency, dynamic form
}

// ❌ BAD: ForbidUsingStaticProperties
function makeRequest(): void {
    $timeout = Config::$timeout;  // Global state via static property
}

// ❌ BAD: ForbidUsingClassConstants
function retry(): void {
    for ($i = 0; $i < Config::MAX_RETRIES; $i++) { /* ... */ }
}

// ❌ BAD: ForbidImpureGlobalFunctions
function generateId(): string {
    return time() . '-' . rand();  // Hidden dependencies on system clock and RNG
}

// ✅ GOOD: Pass values explicitly
function callApi(string $apiKey): void {
    // Use $apiKey parameter
}

function makeRequest(int $timeout): void {
    // Use $timeout parameter
}

function generateId(int $timestamp, int $random): string {
    return $timestamp . '-' . $random;  // Deterministic, testable
}