php 5.3 후 정적 귀속 용법 상세 설명

본 논문 의 사례 는 phop 5.3 후 정적 바 인 딩 용법 을 서술 하 였 다.여러분 께 참고 하도록 공유 하 겠 습 니 다.구체 적 으로 는 다음 과 같 습 니 다.
매 뉴 얼 원문:
PHP 5.3.0 부터 PHP 는 후기 정적 바 인 딩 이라는 기능 을 추가 하여 계승 범위 내 에서 정적 호출 클래스 를 참조 합 니 다.
정확히 말 하면 후기 정적 바 인 딩 작업 원 리 는 이전'비 퍼 가기 호출'(non-forwarding call)에 저 장 된 클래스 입 니 다.정적 방법 을 호출 할 때 이 유형 은 명확 하 게 지정 한 것 입 니 다(보통:연산 자 왼쪽 부분).비정 상 방법 을 호출 할 때 이 대상 에 속 하 는 클래스 입 니 다.이른바'퍼 가기 호출'(forwarding call)이란 다음 과 같은 몇 가지 방식 으로 진행 되 는 정적 호출 을 말한다.self::,parent::,static::그리고 forwardstatic_call()。사용 가능 한 getcalled_class()함 수 는 호출 된 방법 이 있 는 클래스 이름 을 얻 습 니 다.static::그 범 위 를 지적 합 니 다.
이 기능 은 언어 내부 측면 에서'후기 정적 바 인 딩'으로 명 명 된 것 을 고려한다.'후기 귀속정적 방법의 호출 에 사용 할 수 있 기 때문에'정적 귀속'이 라 고도 할 수 있다.
제한
self::또는 사용CLASS__ 현재 클래스 에 대한 정적 인용 은 현재 방법 이 있 는 클래스 를 정의 하 는 데 달 려 있 습 니 다.
Example\#1 self::용법

<?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
후기 정적 바 인 딩 의 용법 후기 정적 바 인 딩 은 새로운 키 워드 를 도입 하여 실행 할 때 최초 로 호출 된 클래스 로 제한 을 돌 리 려 고 했 습 니 다.쉽게 말 하면 이 키 워드 는 상기 예 에서 test()를 호출 할 때 A 가 아 닌 B 를 참조 할 수 있 습 니 다.최종 적 으로 새로운 키 워드 를 도입 하지 않 고 예 정 된 static 키 워드 를 사용 하기 로 했다.
Example\#2 static::간단 한 용법

<?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();
?> 

이상 루틴 출력:
B
참고:비 정적 환경 에서 호출 된 클래스 는 이 대상 의 실례 에 속 하 는 클래스 입 니 다.$this->는 같은 역할 범위 내 에서 개인 적 인 방법 을 사용 하려 고 시도 하기 때문에 static::다른 결 과 를 내 놓 을 수 있 습 니 다.또 다른 차 이 는 static::정적 속성 에 만 사용 할 수 있 습 니 다.
Example\#3 비정 상 환경 에서 static 사용::

<?php
class A {
private function foo() {
echo "success!
"; } public function test() { $this->foo(); static::foo(); } } class B extends A { /* foo() will be copied to B, hence its scope will still be A and * the call be successful */ } class C extends A { private function foo() { /* original method is replaced; the scope of the new one is C */ } } $b = new B(); $b->test(); $c = new C(); $c->test(); //fails ?>
이상 루틴 출력:
success!
success!
success!
Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on line 9
참고:후기 정적 바 인 딩 에 대한 분석 은 완전히 분 석 된 정적 호출 을 얻 을 때 까지 합 니 다.다른 한편,정적 호출 이 parent::또는 self::를 사용 하면 호출 정 보 를 전달 합 니 다.
Example\#4 퍼 가기 와 비 퍼 가기 호출

<?php
class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."
"; } } class B extends A { public static function test() { A::foo(); parent::foo(); self::foo(); } public static function who() { echo __CLASS__."
"; } } class C extends B { public static function who() { echo __CLASS__."
"; } } C::test(); ?>
이상 루틴 출력:
A
C
C
다음 예제 에 서 는 PHP 후기 정적 바 인 딩 기능 을 바탕 으로 계승 범위 내 에서 정적 호출 을 참조 하 는 클래스 를 분석 하 였 다.
먼저 다음 코드 를 보십시오.

class Person
{
public static function status()
{
self::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
Deceased::status(); //Person is alive

결 과 는 우리 가 예상 한 것 이 아니 라 self::실행 중인 클래스 가 아니 라 정 의 된 클래스 에 달 려 있 기 때 문 입 니 다.이 문 제 를 해결 하기 위해 서 는 상속 클래스 에 status()방법 을 다시 쓸 수 있 습 니 다.더 좋 은 해결 방안 은 PHP 5.3 이후 후기 정적 바 인 딩 기능 을 추가 하 는 것 입 니 다.
코드 는 다음 과 같 습 니 다:

class Person
{
public static function status()
{
static::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
Deceased::status(); //Person is deceased

이 를 통 해 알 수 있 듯 이 static::현재 있 는 클래스 를 가리 키 지 않 습 니 다.실제로 실행 중 에 계 산 된 것 으로 최종 클래스 의 모든 속성 을 강제로 가 져 옵 니 다.
따라서 앞으로 self::,static::를 사용 하지 않 는 것 을 권장 합 니 다.
보충:
네티즌
php 의 후기 정적 연결 은 어떻게 설명 합 니까?아래 의 이 그림 출력 은 A,C,C 입 니 다.

그림 의 계승 관 계 를 통 해 알 수 있 듯 이 C 는 B 와 A 를 철저히 포함 하고 있다.
답 결 과 를 보기 전에 그 는 세 가지 유형 에 모두 같은 이름 who()방법 이 있다 는 것 을 자세히 관찰 했다.
시스템 은 마지막 우선 순위 가 가장 높 습 니 다.더 나 아가 C 를 통 해 A,B 안의 who()를 호출 할 수 없습니다.예 를 들 어 getBWho(){echo B:who()를 추가 할 수 밖 에 없습니다.}
그리고 C::getBWho()를 통 해B 내의 who()호출 하기;
다음은 실행 결 과 를 보 겠 습 니 다.
test 는 B 에서 만 나타 나 기 때문에 결 과 는 반드시 test()에서 실 행 된 세 가지 결과 입 니 다.
첫 번 째:정적 으로 성 을 직접 가리 키 는 호출 A 내 정적 함수 입 니 다.이것 은 서 스 펜스 가 없 으 면 반드시 A 입 니 다.
두 번 째:parent::이전 단계 의 부모 클래스 를 호출 하 는 것 입 니 다.이 문제 에서 A 이 고 A 에서 static:who()를 직접 호출 합 니 다.위 에서 말 했 듯 이 who()우선 순 위 는 C 에서 가장 높 습 니 다.ABC 에서 어디서 호출 되 든 static:who()는 반드시 마지막 으로 정 의 된 것 입 니 다.덮어 쓰기 효 과 를 호출 하려 면 A:who()를 호출 하거나 static 을 제거 하여 역할 영역 제한 에서 이 루어 져 야 합 니 다.그래서 이 who()는 C 에서 정 의 된 who 입 니 다.
세 번 째:self::who 는 두 번 째 와 유사 한 문제 입 니 다.모양 을 보면 B 를 가 야 합 니 다.커버 효과 에 주의 하 세 요.B 안의 who 를 호출 하려 면 B:who()를 사용 해 야 합 니 다.더 높 은 C 는 이미 이 방법 을 다시 썼 기 때 문 입 니 다.C 에 who 가 없 으 면 B 일 것 입 니 다.순서대로 유추 해 야 합 니 다.그래서 반드시 C 중의 who 를 호출 합 니 다.
그래서 정 답 은:ACC
코드 는 다음 과 같 습 니 다:

<?php
class A {
  public static function foo() {
    static::who();
  }
  public static function who() {
    echo __CLASS__."
"; } } class B extends A { public static function test() { A::foo(); parent::foo(); self::foo(); } public static function who() { echo __CLASS__."
"; } } class C extends B { //public static function who() { // echo __CLASS__."
"; //} } C::test(); ?>
출력:A B B
네티즌
(위 그림 의 코드 를 대상 으로)
수첩 은 분명히 말 했 잖 아 요.
'후기 귀속'은 static::현재 방법 이 있 는 클래스 를 정의 하 는 것 이 아니 라 실제 실행 할 때 계산 한 다 는 뜻 이다.정적 바 인 딩 이 라 고도 할 수 있 습 니 다.정적 방법의 호출 에 사용 할 수 있 기 때 문 입 니 다.
\#1 작은 질문 이 있 습 니 다.
【self::foo(); // 이 self 는 실제로 C 류 이다.알 겠 느 냐?C::test()C 는 B 의 test()방법 을 계승 했다.]
정확 하지 않 습 니 다.self 는 B 류 이지 만 그 자체 에 foo 방법 이 없 기 때문에 부모 류 A 의 foo 방법 을 사용 합 니 다.
self 가 실제로 C 류 라면 self::foo()를 시도 해 보 세 요.self::who();C 를 인쇄 해 야 하지만 B 를 인쇄 하 는 것 도 self 와 static 의 차이 입 니 다.

<?php
class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."
"; } } class B extends A { public static function test() { A::foo(); parent::foo(); self::who(); } public static function who() { echo __CLASS__."
"; } } class C extends B { public static function who() { echo __CLASS__."
"; } } C::test(); ?>
출력:A C B
네티즌

A::foo(); //A  A ,  A  foo   who  
parent::foo();//  B    ――A foo  ,   foo          C
self::foo(); //self         , B,  B    foo  ,        C    ,
//      foo  ,    c who  ;

그래서 위층 의 질문 에 대답 했다.self:foo()를self::who(),self 가 B 를 가리 키 고 B 는 who 방법 이 있 기 때문에 결 과 는 B 가 됩 니 다.
정적 호출 은 parent::또는 self::원본 호출 정 보 를 전달 합 니 다.
더 많은 PHP 관련 내용 에 관심 이 있 는 독자 들 은 본 사이트 의 주 제 를 볼 수 있다.
본 논문 에서 말 한 것 이 여러분 의 PHP 프로 그래 밍 에 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기