>백엔드 개발 >PHP 튜토리얼 >PHP 지연 정적 바인딩에 대해 자세히 살펴보기

PHP 지연 정적 바인딩에 대해 자세히 살펴보기

不言
不言원래의
2018-04-09 15:24:521331검색

이 글은 주로 PHP 지연 정적 바인딩에 대한 관련 정보를 소개합니다. 도움이 필요한 친구들이 참고할 수 있습니다.

이른바 지연 정적 바인딩이라고 합니다. 이름에서 알 수 있듯이 정적 호출 :: 기호 왼쪽의 바인딩은 지연됩니다. 즉, 더 이상 현재 메서드가 정의된 클래스로 구문 분석되지 않고 실제 런타임에 계산됩니다. 이번 글에서는 주로 PHP 지연 정적 바인딩에 대한 관련 내용을 소개합니다. 아래에서는 자세히 설명하지 않겠습니다. 자세한 소개를 살펴보겠습니다.

뭔가 안 좋은 냄새가 나네요

그동안 프로젝트 백그라운드에서 PHP 코드를 보다가 다음과 비슷한 코드를 보았습니다.

<?php
 class DBHandler {
  function get() {}
 }

 class MySQLHandler extends DBHandler {
  // 这里一个create
  public static function create() {
   echo "MySQL";
   return new self();
  }
  public function get() {
   echo "MySQL get()";
  }
 }

 class MemcachedHandler extends DBHandler {
  // 这里又有一个create
  public static function create() {
   echo "Memcached";
   return new self();
  }
  public function get() {
   echo "Memcached get";
  }
 }

 function get(DBHandler $handler) {
  $handler->get();
 }
 $dbHandler = MySQLHandler::create();
 get($dbHandler);
?>
.

잘못된 코드 냄새가 났나요? 보시다시피 MySQLHandler 및 MemcachedHandler 클래스에 생성 함수가 있습니다. 출력 문을 제거한 후 이것이 코드 중복이라는 것을 알았습니다. 예, 코드 리팩토링이 필요합니다.

간단한 리팩토링 수행

코드 리팩토링은 어디에나 있고 그것에 대해 생각하고 개선이 있다고 느끼는 한 키보드를 누르고 작업을 시작해야 합니다. 자, 위의 코드를 다음과 같이 리팩토링하세요.

<?php
 class DBHandler {
  public static function create() {
   echo "create";
   return new self();
  }
  function get() {}
 }

 class MySQLHandler extends DBHandler {
  public function get() {
   echo "MySQL get()";
  }
 }

 class MemcachedHandler extends DBHandler {
  public function get() {
   echo "Memcached get";
  }
 }

 function get(DBHandler $handler) {
  $handler->get();
 }
 $dbHandler = MySQLHandler::create();
 get($dbHandler);
?>

생성 함수를 DBHandler 클래스로 이동하면 좋아 보입니다. 적어도 하나 이상의 잘못된 코드가 제거됩니다.

잘못된 것 같습니다

실행해 보았는데 예상한 대로 인쇄되지 않았습니다. 이 코드에 문제가 있습니다. 이게 뭐가 문제야? 이는 오늘 요약의 초점인 지연된 정적 바인딩으로 이어집니다.

MySQL get()  。什么情况?这说明,并没有调用MySQLHandler的get函数,但是代码明明调用了啊,这说明, new self() 지연 정적 바인딩

지연 정적 바인딩은 PHP5.3 이후에 도입되었습니다. 다음 코드를 다시 살펴보세요.

<?php
 class A {
  public static function who() {
   echo __CLASS__;
  }
  public static function test() {
   self::who();
  }
 }

 class B extends A {
  public static function who() {
   echo __CLASS__;
  }
 }
 B::test();
?>

위 코드는 A를 출력하는데 B를 출력하고 싶습니다. 이것이 문제입니다. 이는 self와 __CLASS__의 제한 사항이기도 합니다. 현재 메서드가 정의된 클래스에 따라 self:: 또는 __CLASS__를 사용하는 현재 클래스에 대한 정적 참조입니다. 따라서 이는 위 코드가 A를 출력하는 이유를 매우 잘 설명합니다. 하지만 B를 출력해야 한다면 어떻게 될까요? 다음과 같이 할 수 있습니다:

<?php
 class A {
  public static function who() {
   echo __CLASS__;
  }
  public static function test() {
   static::who(); // 这里有变化,后期静态绑定从这里开始
  }
 }

 class B extends A {
  public static function who() {
   echo __CLASS__;
  }
 }
 B::test();
?>

후기 정적 바인딩은 원래 런타임에 처음 호출되는 클래스를 나타내는 새 키워드를 도입하여 제한을 우회하려고 했습니다. 간단히 말해서, 이 키워드를 사용하면 위 예제에서 test()를 호출할 때 A 클래스 대신 B 클래스를 참조할 수 있습니다. 결국 새로운 키워드를 도입하지 않고 이미 예약된 정적 키워드를 사용하기로 결정되었습니다.

이것은 후기 정적 바인딩의 근원입니다. 이는 static 키워드의 대체 사용입니다. 기사 시작 부분의 예를 들어 다음과 같이 변경할 수 있습니다.

return new static(); // 改变这里,后期静态绑定

후기 정적 바인딩을 사용하면 PHP를 사용하여 23가지 디자인 패턴을 구현할 때 매우 편안함을 느낄 수 있습니다.

요약

아주 간단한 지식 포인트지만, 정리하자면 몇 가지 정보를 확인하고 지식 포인트를 보완했습니다. 과거를 검토하고 새로운 것을 배우십시오. 알겠습니다. 이것이 모두에게 도움이 되기를 바랍니다. 내 기사를 더 좋게 만들기 위한 제안 사항이 있으면 언제든지 문의하세요. 도움이 필요합니다.
관련 권장 사항:

PHP 지연 정적 바인딩 정적 세부 설명

php는 늦은 정적 바인딩을 구현합니다


위 내용은 PHP 지연 정적 바인딩에 대해 자세히 살펴보기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.