← Назад к вопросам

Знаешь что такое позднее статическое связывание?

2.0 Middle🔥 91 комментариев
#PHP Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Позднее Статическое Связывание (Late Static Binding)

Позднее статическое связывание — это механизм в PHP, который позволяет обращаться к методам и свойствам класса, вызвавшего метод, а не к классу, в котором метод определён. Используется ключевое слово static:: вместо self::.

Проблема self vs static

// Проблема с self
class Parent {
    public static function whoAmI() {
        echo self::class; // Всегда Parent!
    }
    
    public static function identify() {
        self::whoAmI();
    }
}

class Child extends Parent {
    public static function whoAmI() {
        echo self::class; // Child
    }
}

Child::identify(); // Выведет: Parent (неправильно!)

// Решение с static
class Parent {
    public static function whoAmI() {
        echo static::class; // Выведет вызывающий класс
    }
    
    public static function identify() {
        static::whoAmI();
    }
}

class Child extends Parent {
    public static function whoAmI() {
        echo static::class; // Child
    }
}

Child::identify(); // Выведет: Child (правильно!)

Практические примеры

Factory паттерн с наследованием:

abstract class Model {
    public static function create($data) {
        $instance = new static();
        $instance->fill($data);
        return $instance;
    }
    
    protected function fill($data) {
        foreach ($data as $key => $value) {
            $this->$key = $value;
        }
    }
}

class User extends Model {}
class Product extends Model {}

// Вернёт User, не Model
$user = User::create(['name' => 'John', 'email' => 'john@example.com']);

// Вернёт Product, не Model
$product = Product::create(['name' => 'Laptop']);

Синглтон с наследованием:

class Singleton {
    private static $instances = [];
    
    protected function __construct() {}
    
    public static function getInstance() {
        $class = static::class;
        
        if (!isset(self::$instances[$class])) {
            self::$instances[$class] = new static();
        }
        
        return self::$instances[$class];
    }
}

class Database extends Singleton {}
class Logger extends Singleton {}

// Разные синглтон экземпляры
$db1 = Database::getInstance();
$db2 = Database::getInstance();
echo $db1 === $db2; // true

$logger1 = Logger::getInstance();
echo $db1 === $logger1; // false

self vs static vs $this

class A {
    public static function staticMethod() {
        echo static::class; // Вызывающий класс
    }
    
    public static function staticSelf() {
        echo self::class; // A (раннее связывание)
    }
    
    public function instanceMethod() {
        echo static::class; // Работает и в методах экземпляра
    }
}

class B extends A {}

B::staticMethod(); // B (static)
B::staticSelf(); // A (self)
$b = new B();
$b->instanceMethod(); // B (static)

Когда использовать static::

  • Factory методы — new static() создаст экземпляр вызвавшего класса
  • Синглтоны — каждый класс получит свой экземпляр
  • Callback методы — когда нужен полиморфизм
  • Template method паттерн — подклассы переопределяют методы
Знаешь что такое позднее статическое связывание? | PrepBro