Рубрики
Uncategorized

Использование поздних статических привязок в PHP

Автор оригинала: David Wong.

Суффикс

Поздняя статическая привязка статическая:: Прежде всего, нам нужно четко понимать использование в классе, статическая:: Последующая проверка Константа класса |/、 Статические свойства (переменные класса) |/、 Статический метод и Общий метод (при следовании константе класса/статическое свойство/статический метод статический При представлении класса и обычного метода статический Представляет объект), Его нельзя сравнивать с обычным свойством (переменная-член объекта), потому что семантически невозможно отличить, является ли это обычным атрибутом или статическим атрибутом (синтаксис статический:: $XX).

Цель введения

Цель введения поздней статической привязки состоит в том, чтобы нарушить self:: Ограничения на ключевые слова в классе self Направление определяется в контексте кода во время компиляции self класса. и static:: Он определяет свое направление во время выполнения. В отношениях наследования мы можем видеть, что self и статический Разница.

Сценарии использования

Статический:: сценарий с константой класса

class A {
    public const FOO = 'a';

    public function test() {
        Echo self:: foo; // self explicitly points to the class A in the code context. Even if it is called by a subclass, self also points to a
    }
}

class B extends A {
    public const FOO = 'b';
}

(New B) - > test(); // output a
class A {
    public const FOO = 'a';

    public function test() {
        Echo static:: foo; // static points to the caller only when it is uncertain during compilation. Therefore, it is called "late binding". Here static is followed by class constant, so static represents calling class, i.e. class B.
    }
}

class B extends A {
    public const FOO = 'b';
}

(New B) - > test(); // output B

Статика:: сцена со статическим атрибутом (то же самое)

class A {
    public static $foo = 'a';

    public static function test() {
        echo self::$foo;
    }
}

class B extends A {
    public static $foo = 'b';
}

B:: test(); // output a
class A {
    public static $foo = 'a';

    public static function test() {
        echo static::$foo;
    }
}

class B extends A {
    public static $foo = 'b';
}

B:: test(); // output B

Статический:: сценарий со статическими методами

class A {
    public static function who() {
        Echo class is bound with a class name at compile time
    }
    public static function test() {
        Self:: who(); // self points to class A at compile time
    }
}

class B extends A {
    public static function who() {
        Echo class is bound with the B class name at compile time
    }
}

B::test(); // A
class A {
    public static function who() {
        echo __CLASS__;
    }
    public static function test() {
        Static:: who(); // late binding
    }
}

class B extends A {
    public static function who() {
        echo __CLASS__;
    }
}

B::test(); // B

Статический:: сценарий с обычными методами

В дополнение к замене self:: , static:: Его также можно заменить в некоторых сценах $this -> . Существует сценарий, в котором, когда метод в родительском классе вызывается подклассом, $this – > в методе сначала ищет частный метод или свойство в его области (контекст кода, то есть родительский класс). Если он не может его найти, он вызовет метод или свойство своего подкласса. Статика относится к поздней привязке. Вы можете обойти этот шаг и указать непосредственно на вызывающего метод.

class A {
    private function foo() {
        echo "a\n";
    }

    public function test() {
        $this - > foo(); // the private method foo exists in the scope, so the foo method in B will not be called
    }
}

class B extends A {
    public function foo() {
        echo "b\n";
    }
}

(New B) - > test(); // output a
class A {
    private function foo() {
        echo "a\n";
    }

    public function test() {
        Static:: foo(); // bypass the check and call the caller's method directly
    }
}

class B extends A {
    public function foo() {
        echo "b\n";
    }
}

(New B) - > test(); // output B