LSB(Late Static Binding)
이번 주제는 LSB(Late Static Binding)입니다.
PHP 5.3 버전에서부터 도입된 개념입니다.
중요한 부분은
can be used to reference the called class in a context of static inheritance
( 정적 상속의 상황에서 호출전 클래스를 참조 할 수 있다.)
More precisely, late static bindings work by storing the class named in the last "non-forwarding call"
( 좀 더 명확히 이야기 하자면 LSB는 최근 비 전송콜의 class이름을 저장한다. )
ㅂ가 매우 중요한 부분 인 것 같습니다.
그럼 예제를 보면서 이야기 해 볼까요
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?php abstract class car { protected static $price = null; public static function getPrice() { return number_format( self::$price ); } } class Toyota extends car{ protected static $price = 100000; } var_dump( Toyota::getPrice() ); | cs |
이런 경우 딱 보면 14000을 출력 할 것 같지만 이 결과는 0 입니다.
PHP의 매뉴얼을 다시 들여다 보면
( self:: 또는 __CLASS__에 대한 현재 클래스에 대한 정적 참조는 그 메소드가 속한 Class ( 즉 그 메소드가 정의되어 있는 class )를 나타낸다 )
즉 위의 예제를 바탕 으로 이야기 하면 getPrice함수는 Car클래스에 속해 있기 때문에 self::가 참조 하는 $price는 Car가 가지고 있는
price 뜻 하는 것 입니다.
이렇게 되면 아무리 Car를 상속하는 여러 가지 자동차를 생산 하더라도 getPrice를 사용 할 수 없게 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php abstract class car { protected static $price = null; public static function getPrice() { return number_format( static::$price ); } } class Toyota extends car { protected static $price = 100000; } var_dump( Toyota::getPrice() ); // 100.000 | cs |
예제와 같이 self를 static으로 교환하면 원하는 14000이 출력 되는 것 을 확인 할 수 있습니다.
references the class that was initially called at runtime
( 실행시에 최초에 콜 당한 클래스를 참조함 )
이말은 위 예제에서 static::$price 는 Toyota::$price를 참조한다는 의미 가 됩니다.
자 그럼 좀 더 살펴 볼까요
아까 위에서
More precisely, late static bindings work by storing the class named in the last "non-forwarding call"
( 좀 더 명확히 이야기 하자면 LSB는 최근 비 전송콜의 class이름을 저장한다. )
이런 설명이 있었습니다. 예제 보시죠
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php abstract class car{ protected static $price = null; public static function getPrice() { return number_format( static::$price ); } public static function getDescription() { return 'price is ' . car::getPrice(); } } class Toyota extends car { protected static $price = 100000; } var_dump( Toyota::getDescription() ); // 0 | cs |
이렇게 짜여진 경우 도요타의 getDescription을 실행하면 static::$price는 Toyota::$price를 참조 할 것 이라 생각하지만
실제로는 car::$price를 참조 하고 있습니다.
즉 가장 최근에 불려진 비 전송 콜인 Car::getPrice()의 영향으로 Car::$price가 참조 되고 있다는 의미 입니다.
LSB에 대한 설명은 여기 까지 입니다.
이런 기능에 대해선 잘 알게 되어서 기쁘지만 아직 많은 코딩을 경험 해 보지 못한 뉴비로써 어떤 경우 이런걸 사용하고
저런걸 사용할지 아직 명확히 감이 잡히지 않네요.
뭐 알아두면 언젠간 써 먹겟죠!
이 LSB에 대해 사내에 실력 높은 개발자 분과 이야기를 나누어 봤습니다.
복잡해 보이는 개념, 사용법, 스코프 구분 등 복잡해 보이는게 아니라 걍 복잡합니다. 솔직히 static은 스코프를 나눠 주는 그런 녀석입니다.
따라서 여태 하듯이 this->를 사용 한다면 별다른 문제 없이 사용 할 수 있지만 static의 특성인 memoization을 이용한 하이퍼포먼스의 구현, 불필요한 메모리 사용 제거 등 개발자로서의 실력이 향상 되었을 때에 나타나는 퍼포먼스 개선등에 이용이 가능하다고 합니다.
물론 그런 고급기술을 공짜로 얻을 순 없겟죠? 머리가 복잡해지는 건 당연하다고 하시네요.