문제

PHP의 늦은 정적 바인딩은 정확히 무엇입니까?

도움이 되었습니까?

해결책

당신은 확실히 읽어야합니다 늦은 정적 바인딩 PHP 매뉴얼에서. 그러나 나는 당신에게 빠른 요약을 제공하려고 노력할 것입니다.

기본적으로 그것은 self 키워드는 동일한 상속 규칙을 따르지 않습니다. self 항상 사용되는 클래스로 해결됩니다. 이것은 부모 수업에서 메소드를 만들고 어린이 수업에서 전화하면 self 예상대로 자녀를 참조하지 않습니다.

늦은 정적 바인딩은 새로운 용도를 도입합니다 static 이 특정 단점을 다루는 키워드. 당신이 사용할 때 static, 그것은 당신이 처음 사용하는 클래스를 나타냅니다 (즉). 런타임 클래스에 '바인딩'합니다.

그것들은 그 뒤에있는 두 가지 기본 개념입니다. 길 self, parent 그리고 static 언제 작동합니다 static 작용하는 것은 미묘 할 수 있으므로 더 자세히 설명하기보다는 수동 페이지 예제를 연구하는 것이 좋습니다. 각 키워드의 기본 사항을 이해하면 어떤 종류의 결과를 얻을 수 있는지 예제가 필요합니다.

다른 팁

PHP 5.3.0 현재, PHP는 정적 상속의 맥락에서 호출 클래스를 참조하는 데 사용할 수있는 후기 정적 바인딩이라는 기능을 구현합니다.

늦은 정적 바인딩은 런타임에 처음 호출 된 클래스를 참조하는 키워드를 소개하여 해당 제한을 해결하려고합니다. 새로운 키워드를 소개하지 않고 오히려 사용하기로 결정했습니다. static 이미 예약되었습니다.

예를 들어 보자 :

<?php
    class Car
    {
        public static function run()
        {
            return static::getName();
        }

        private static function getName()
        {
            return 'Car';
        }
    }

    class Toyota extends Car
    {
        public static function getName()
        {
            return 'Toyota';
        }
    }

    echo Car::run(); // Output: Car
    echo Toyota::run(); // Output: Toyota
?>

late static bindings 마지막 "비 포드 콜"에 이름이 지정된 수업을 저장하여 작업합니다. 정적 메소드 호출의 경우, 이것은 명시 적으로 명명 된 클래스입니다 (일반적으로 :: 연산자의 왼쪽에있는 것). 비 정적 메소드 호출의 경우 객체의 클래스입니다.

"전달 호출"은 self::, parent::, static::, 또는 클래스 계층 구조에서 올라가는 경우 forward_static_call().

함수 get_called_class() 호출 클래스의 이름으로 문자열을 검색하는 데 사용할 수 있으며 static:: 그 범위를 소개합니다.

명백한 행동은 없습니다.

다음 코드는 '알파벳'을 생성합니다.

class alpha {

    function classname(){
        return __CLASS__;
    }

    function selfname(){
        return self::classname();
    }

    function staticname(){
        return static::classname();
    }
}

class beta extends alpha {

    function classname(){
        return __CLASS__;
    }
}

$beta = new beta();
echo $beta->selfname(); // Output: alpha
echo $beta->staticname(); // Output: beta

그러나 베타 클래스에서 ClassName 함수의 선언을 제거하면 결과적으로 '알파 알파'가 나타납니다.

이 책에서 "PHP Master Write Cutting-Edge Code"를 인용하고 있습니다.

후기 정적 결합은 PHP 5.3과 함께 도입 된 특징이었다. 이를 통해 부모 클래스에서 정적 메소드를 상속하고 호출되는 아동 수업을 참조 할 수 있습니다.

즉, 정적 메소드가있는 추상 클래스를 가질 수 있고 사용하여 아동 클래스의 구체적인 구현을 참조 할 수 있습니다. 정적 :: 메소드 () 자기 대신 표기법 :: 메소드 ().

공식 PHP 문서를 자유롭게 살펴보십시오.http://php.net/manual/en/language.oop5.late-static-bindings.php


늦은 정적 바인딩을 설명하는 가장 분명한 방법은 간단한 예제입니다. 아래의 두 클래스 정의를 살펴보고 계속 읽으십시오.

class Vehicle {
    public static function invokeDriveByStatic() {
        return static::drive(); // Late Static Binding
    }
    public static function invokeStopBySelf() {
        return self::stop(); // NOT Late Static Binding
    }
    private static function drive(){
        return "I'm driving a vehicle";
    }
    private static function stop(){
        return "I'm stopping a vehicle";
    }
}

class Car extends Vehicle  {
    protected static function drive(){
        return "I'm driving a CAR";
    }
    private static function stop(){
        return "I'm stopping a CAR";
    }
}

우리는 부모 수업 (차량)과 어린이 수업 (자동차)을 볼 수 있습니다. 부모 수업에는 두 가지 공개 방법이 있습니다.

  • invokeDriveByStatic
  • invokeStopBySelf

부모 클래스에는 두 가지 개인 방법이 있습니다.

  • drive
  • stop

어린이 수업은 두 가지 방법을 무시합니다.

  • drive
  • stop

이제 공개 방법을 호출합시다.

  • invokeDriveByStatic
  • invokeStopBySelf

스스로에게 물어보십시오 : 어떤 수업이 호출되는지 invokeDriveByStatic / invokeStopBySelf? 부모 또는 자녀 수업?

아래를 살펴보십시오.

// This is NOT Late Static Binding
// Parent class invokes from Parent. In this case Vehicle.
echo Vehicle::invokeDriveByStatic(); // I'm driving a vehicle
echo Vehicle::invokeStopBySelf(); // I'm stopping a vehicle

// This is Late Static Binding.
// Child class invokes an inherited method from Parent.
// Child class = Car, Inherited method = invokeDriveByStatic().
// ...
// The inherited method invokes a method that is overridden by the Child class.
// Overridden method = drive()
echo Car::invokeDriveByStatic(); // I'm driving a CAR

// This is NOT Late Static Binding
// Child class invokes an inherited method from Parent.
// The inherited method invokes a method inside the Vehicle context.
echo Car::invokeStopBySelf(); // I'm stopping a vehicle

그만큼 static 키워드는 싱글 톤 디자인 패턴으로 사용됩니다. 링크 참조 : https://refactoring.guru/design-patterns/singleton/php/example

차이를 보여주는 가장 간단한 예.
메모, 자기 :: $ c

class A
{
    static $c = 7;

    public static function getVal()
    {
        return self::$c;
    }
}

class B extends A
{
    static $c = 8;
}

B::getVal(); // 7

늦은 정적 결합, 참고 정적 :: $ c

class A
{
    static $c = 7;

    public static function getVal()
    {
        return static::$c;
    }
}

class B extends A
{
    static $c = 8;
}

B::getVal(); // 8

예를 들어:

abstract class Builder {
    public static function build() {
        return new static;
    }
}

class Member extends Builder {
    public function who_am_i() {
         echo 'Member';
    }
}

Member::build()->who_am_i();

"왜 내가 이것을 사용하겠습니까?" 관점에서, 그것은 기본적으로 정적 메소드가 해석/실행되는 컨텍스트를 변경하는 방법입니다.

와 함께 self, 컨텍스트는 원래 메소드를 정의한 컨텍스트입니다. 와 함께 static, 그것은 당신이 그것을 부르는 것입니다.

또한 하위 수업에서 정적 변수를 업데이트하는지 확인하십시오. 자식 B가 자녀 C를 업데이트하는이 (다소) 예상치 못한 결과를 발견했습니다.

class A{
    protected static $things;
}

class B extends A {
    public static function things(){
        static::$things[1] = 'Thing B';
        return static::$things; 
    }
}

class C extends A{
    public static function things(){
        static::$things[2] = 'Thing C';
        return static::$things;        
    }
}

print_r(C::things());
// Array (
//   [2] => Thing C
// )

B::things();

print_r(C::things()); 
// Array (
//    [2] => Thing C
//    [1] => Thing B
// )

예를 들어 각 어린이 수업에서 동일한 변수를 선언하여이를 수정할 수 있습니다.

class C extends A{
    protected static $things; // add this and B will not interfere!

    public static function things(){
        static::$things[2] = 'Thing C';
        return static::$things;        
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top