DEV Community

Cover image for Exploring Late Static Binding in PHP
Al Amin
Al Amin

Posted on

Exploring Late Static Binding in PHP

🧠 PHP Late Static Binding Explained: self:: vs static:: vs new static() for Real-World Use

Hey fellow devs,

Ever found yourself confused by the difference between self::, static::, new self() and new static() in PHP?

I did too. Until I slowed down, played with examples, and finally understood the beauty of something called Late Static Binding (LSB).

Let’s break it down like we’re talking over a project debug session.


🤔 What’s the Problem?

You have a parent class that defines a static method. You extend it with a child class and call the method from the child. But surprisingly, the method behaves like it’s still running in the parent.

Like this:

class ParentClass { public static function whoAmI() { echo "I am " . self::class; } } class ChildClass extends ParentClass {} ChildClass::whoAmI(); // ❌ Output: I am ParentClass 
Enter fullscreen mode Exit fullscreen mode

Why did it say ParentClass? You called it from ChildClass, right?

Because self:: refers to the class where the method is defined, not who called it.

And that's the limitation Late Static Binding solves.


🛠 Enter: static:: — the Fix

class ParentClass { public static function whoAmI() { echo "I am " . static::class; } } class ChildClass extends ParentClass {} ChildClass::whoAmI(); // ✅ Output: I am ChildClass 
Enter fullscreen mode Exit fullscreen mode

That’s it! With static::, PHP waits until runtime to figure out which class is calling. Hence the term late binding.


🧪 self::class vs static::class

Keyword What it returns When it's resolved
self::class The class where it's written At compile time
static::class The class that called it At runtime ✅

This is especially powerful in patterns like factories or service locators.


🎭 Object Creation: new self() vs new static()

Let’s create objects and see the difference:

class Animal { public static function create() { return new static(); // 👈 creates the calling class } } class Dog extends Animal {} class Cat extends Animal {} $dog = Dog::create(); $cat = Cat::create(); echo get_class($dog); // Dog ✅ echo get_class($cat); // Cat ✅ 
Enter fullscreen mode Exit fullscreen mode
  • new static() → respects the child class
  • new self() → would have returned Animal in both cases ❌

So again...

Expression What it does
new self() Create object of defined class
new static() Create object of calling class ✅

🔌 Real Use Case (Like in a Plugin)

Imagine you're building a WordPress plugin with multiple shortcode handlers. You could create a BaseShortcode like this:

class BaseShortcode { public static function init() { echo "Booting: " . static::class . "\n"; return new static(); // 🎯 } } class GalleryShortcode extends BaseShortcode {} class FormShortcode extends BaseShortcode {} $g = GalleryShortcode::init(); // GalleryShortcode $f = FormShortcode::init(); // FormShortcode 
Enter fullscreen mode Exit fullscreen mode

If you had used new self() and self::class, both would have printed BaseShortcode. Not what you want when building reusable code, right?


🧠 Think of It Like This

  • self:: / new self() → fixed, bound to the class that wrote the method
  • static:: / new static() → flexible, bound to the class that called the method

Late static binding gives your OOP code dynamic power while keeping it clean.


🧪 Practice Time

Can you make this code output:

Creating UserController 
Enter fullscreen mode Exit fullscreen mode

👉 Try replacing what’s needed:

class BaseController { public static function load() { echo "Creating " . ???; return ???; } } class UserController extends BaseController {} $ctrl = UserController::load(); 
Enter fullscreen mode Exit fullscreen mode

(Answer: replace ??? with static::class and new static() 😉)


🧵 Final Thoughts

Late static binding might sound fancy, but it's just a tool that lets your code act more like real-world behavior: flexible, extendable, and smart at runtime.

When you’re building reusable components, plugin frameworks, or Laravel-style factories — understanding this makes your OOP code next level.

Top comments (0)