SyntaxStudy
Sign Up
PHP Advanced 10 min read

Late Static Binding

Late Static Binding (LSB) allows a static method to refer to the class it was called on, rather than the class in which it was defined. Use static:: instead of self:: to enable LSB.

  • self:: always refers to the class where the method is physically defined.
  • static:: refers to the class that was invoked at runtime.
  • Essential for correct behaviour in static factory methods and singleton patterns when used with inheritance.
Example
<?php
class Model
{
    // Using self:: — WRONG for inheritance
    public static function createSelf(): static
    {
        return new self(); // Always creates Model, never the child
    }

    // Using static:: — CORRECT for inheritance (LSB)
    public static function create(): static
    {
        return new static(); // Creates the actual called class
    }

    // get_called_class() equivalent: static::class
    public static function getClass(): string
    {
        return static::class; // returns the runtime class name
    }
}

class User extends Model
{
    public string $type = 'user';
}

class Admin extends Model
{
    public string $type = 'admin';
}

$model = Model::create();  // instanceof Model
$user  = User::create();   // instanceof User  ✓
$admin = Admin::create();  // instanceof Admin ✓

echo User::getClass();  // User
echo Admin::getClass(); // Admin

// Practical: active-record style finder
class BaseRecord
{
    private static array $store = [];

    public static function find(int $id): ?static
    {
        return static::$store[$id] ?? null;
    }

    public static function save(int $id, static $record): void
    {
        static::$store[$id] = $record;
    }
}

class UserRecord extends BaseRecord {}

$u = new UserRecord();
UserRecord::save(1, $u);
$found = UserRecord::find(1); // returns UserRecord instance
Pro Tip

Tip: A quick rule: if you want the method to be "self-aware" of the class it was called on (even through inheritance), use static::. If you always want the class where the code lives, use self::. For factory methods and singletons in base classes, almost always use static::.