DEV Community

Cover image for Exploring Static Variable in PHP
Al Amin
Al Amin

Posted on • Edited on

Exploring Static Variable in PHP

Have you ever needed a shared memory drawer in PHP — a place where your data stays accessible between function calls without polluting the global scope?

Welcome to one of PHP’s most underrated advanced techniques: using static variables combined with references to create a persistent, in-memory cache that lives throughout a single request lifecycle.

🚪Imagine Your Function Is a Drawer...

Let’s say you had a magical drawer in your function — one that remembers things every time it’s opened. Better yet, you could hand out references to that drawer so anyone else could add or modify its contents.

That’s exactly what this pattern does:

function &myDrawer(){
    static $drawer = [];
    return $drawer;
}

$sportsClothes = &myDrawer();
$sportsClothes['sports'] = ['trouser', 'jersey', 'cap'];

$winterClothes = &myDrawer();
$winterClothes['winter'] = ['hat', 'jacket', 'thermal-pants'];

print_r( myDrawer() );
Enter fullscreen mode Exit fullscreen mode
Array
(
    [sports] => Array
        (
            [0] => trouser
            [1] => jersey
            [2] => cap
        )
    [winter] => Array
        (
            [0] => hat
            [1] => jacket
            [2] => thermal-pants
        )
)
Enter fullscreen mode Exit fullscreen mode

💥 Why This Is Powerful

Shared memory: All references (&myDrawer()) point to the same underlying static variable.

Encapsulation: No need for global $vars or static class properties.

Persistence during request: The data lives as long as the script runs — great for caching and memoization.

Memory-safe: No memory bloat across requests (unlike Redis or Memcached).

🛠️ Real-Life Use Cases

1. 🔁 In-Memory Caching
Avoid repeating expensive operations like file reads or database calls:

function &configCache() {
    static $cache = [];
    return $cache;
}

function getConfig($key) {
    $cache = &configCache();

    if (!isset($cache[$key])) {
        // simulate expensive config loading
        $cache[$key] = file_get_contents("config/$key.json");
    }

    return $cache[$key];
}
Enter fullscreen mode Exit fullscreen mode

2. 📦 Lightweight Service Container
Store shared services or dependencies without a full-blown framework:

function &container() {
    static $services = [];
    return $services;
}

$container = &container();
$container['logger'] = new Logger();

$logger = &container()['logger'];
$logger->info("App started");
Enter fullscreen mode Exit fullscreen mode

3. 🧪 Unit Test Registry
Pass shared test data between test cases without globals:

function &testRegistry() {
    static $store = [];
    return $store;
}

testRegistry()['user_id'] = 123;
Enter fullscreen mode Exit fullscreen mode

🧠 Behind the Scenes: PHP References + Static Variables
Let’s decode this pattern:

static $var: Keeps the variable alive between function calls — scoped only to that function.

&: The ampersand makes sure you return a reference, not a copy. Without it, any modification won’t persist.

&$myVar = &functionName();: Allows the outer variable to work directly with the shared internal memory.

This is essentially shared memory within a single request, without needing to use classes or superglobals.

📛 What to Call This Pattern?

You could think of it as:

  • Persistent in-function registry
  • Static-reference drawer
  • Local singleton function
  • Scoped memory store
  • Whatever name sticks for you, just know: it’s powerful.

✨ Final Thoughts

This is an advanced but elegant PHP pattern — something you won't see in beginner tutorials, yet immensely useful in plugin development, small frameworks, and anywhere performance and clean structure matter.

✅ TL;DR

  1. Use static to keep memory inside a function.
  2. Use & to share that memory with the outside world.
  3. Ideal for in-memory cache, dependency containers, and temporary registries.

Top comments (3)

Collapse
 
xwero profile image
david duymelinck • Edited

While it is a clever trick, it lacks a lot of functionality.

The common way to achieve the same effect is to have a class with a static property.
The benefit of a class is that it not only encapsulates the variable, but you can add methods that make it easier to work with it.

class Container {
   private static array $services = [];

   public static function addService(string $name, object $service) : void
   {
       // add validation here
       static::$services[$name] = $service;
   }

   public static function getService(string $name) : object|null
   {
      return static::$services[$name] ?? null;
   }
}

Container::addService('logger', new stdClass());

$logger = Container::getService('logger');
Enter fullscreen mode Exit fullscreen mode

I wanted to show the container example of your post, because that example will trigger an exception.
You forgot the ampersand the second time the container function is called.

Collapse
 
dev-alamin profile image
Al Amin

Thanks @david
Yes, you're right.

I have put that for basic skill building, moreover, I will update post with OOP/Encaptulation.

Thanks for typo mistake, I have eddited.

Collapse
 
rfool profile image
Robert Frunzke

What to Call This Pattern?

Singleton.

This is just a plain Singleton. And it is an Anti-Pattern for many reasons.