Computer >> 컴퓨터 >  >> 프로그래밍 >> PHP

PHP 지연 정적 바인딩(Late Static Binding) 완벽 이해하기


지연 정적 바인딩이란?

PHP의 지연 정적 바인딩(Late Static Binding)은 정적 상속 환경에서 실제로 호출된 클래스를 참조할 수 있게 해주는 기능입니다. 정적 메서드를 호출할 때는 범위 지정 연산자(::)와 함께 클래스 이름을 사용하고, 인스턴스 메서드는 객체 이름을 통해 호출합니다. 핵심은 static::이 메서드가 정의된 클래스를 기준으로 해석되지 않고, 런타임 정보를 바탕으로 계산된다는 점입니다. 즉, 현재 클래스에 대한 정적 참조는 함수가 정의된 클래스가 아니라 실제 호출 시점의 클래스를 기준으로 해석됩니다.

self:: 사용 시 발생하는 문제

다음 코드에서 부모 클래스는 self:: 접두사를 사용해 정적 메서드를 호출합니다. 자식 클래스에서 동일한 메서드를 호출하더라도 self::는 런타임에 해석되지 않기 때문에 자식 클래스 이름을 참조하지 않습니다.

예제

<?php
class test1{
    public static $name="Raja";
    public static function name(){
        echo "name of class :" . __CLASS__;
    }
    public static function getname(){
        self::name();
    }
}
class test2 extends test1{
    public static function name(){
        echo "name of class :" . __CLASS__;
    }
}
test2::getname();
?>

출력 결과

예상과 달리 부모 클래스의 이름이 반환되는 것을 확인할 수 있습니다.

name of class :test1

static::을 활용한 지연 바인딩

self:: 대신 static::을 사용하면 런타임에 지연 바인딩이 발생하여, 실제 호출된 클래스가 기준이 됩니다.

예제

<?php
class test1{
    public static function name(){
        echo "name of class :" . __CLASS__;
    }
    public static function getname(){
        static::name();
    }
}
class test2 extends test1{
    public static function name(){
        echo "name of class :" . __CLASS__;
    }
}
test2::getname();
?>

이제 위 코드는 예상대로 자식 클래스의 이름을 반환합니다.

출력 결과

name of class :test2

비정적(non-static) 컨텍스트에서 static:: 사용하기

부모 클래스의 private 메서드는 자식 클래스로 복사되기 때문에, 그 범위(scope)는 여전히 부모 클래스에 머물러 있습니다.

예제

<?php
class test1{
    private function name(){
        echo "name of class :" . __CLASS__ ."\n";
    }
    public function getname(){
        $this->name();
        static::name();
    }
}
class test2 extends test1{
    //
}
$t2=new test2();
$t2->getname();
?>

출력 결과

실행 결과는 다음과 같습니다.

name of class :test1
name of class :test1

그러나 부모의 메서드가 자식 클래스에서 오버라이드되면, 해당 메서드의 범위가 자식 클래스로 변경됩니다.

예제

class test3 extends test1{
    private function name() {
        /* 원본 메서드가 대체되며, name의 범위는 test3이 됨 */
    }
}
$t3 = new test3();
$t3->name();

출력 결과

이 경우 다음과 같은 치명적인 오류가 발생합니다.

PHP Fatal error: Uncaught Error: Call to private method test3::name() from context ''