programing

$ this에 대한 동적 참조는 작동하지 않지만 작동합니다.

javaba 2021. 1. 15. 19:12
반응형

$ this에 대한 동적 참조는 작동하지 않지만 작동합니다.


변수 변수 에 대한 PHP 문서에 따라 :

$ 이것은 동적으로 참조 할 수없는 특수 변수입니다.

그러나 적어도 PHP 버전에서는 테스트 한 것입니다 (5.5.12).

class ThisIsBugged
{
    public function __construct()
    {
        ${'this'}->doSomething(); // This works, while it shouldn't
    }
}

질문 # 1 : 어떻게 작동 할 수 있습니까? 문서에 따르면 안됩니다.

하지만 더 있습니다.

class ThisIsBugged
{
    public function __construct()
    {
        // This does not work, but it could. See below.
        ${'th' . 'is'}->doSomething();
    }
}

예상대로 실행을 중지합니다.

PHP 알림 : 정의되지 않은 변수 : this

PHP 치명적 오류 : 비 객체에서 멤버 함수 doSomething () 호출.

{'th' . 'is'}이 평가되었습니다 : "Undefined variable : this" .

그러나 (이것은 가장 이상한 것입니다) 명시 적으로 특수 변수를 $this참조하면 메서드 내에서 그 전후에 사용 된 모든 동적 참조가 수정됩니다.

class ThisIsBugged
{
    public function __construct()
    {
        // Now it works while it shouldn't
        ${'th' . 'is'}->doSomething();

        // This fixes both the previous and the subsequent calls
        $unused = $this;

        // Now it works while it shouldn't
        ${'th' . 'is'}->doSomething();
    }
}

질문 # 2 :에 대한 명시 적 참조가 전체 메서드에 표시 $this할 다른 모든 동적 참조를 어떻게 수정할 수 $this있습니까?


PHP는 컴파일 된 변수 (CV) 최적화라는 개념을 사용합니다. 즉, 변수 이름을 값에 매핑하는 해시 테이블을 사용하는 대신 일반 배열과 인덱스를 사용합니다. 컴파일러는 어떤 변수 이름이 어떤 인덱스에 해당하는지 알고 있습니다. 배열 인덱스 조회를 수행하는 것이 해시 테이블 조회를 수행하는 것보다 훨씬 빠릅니다.

$this변수는이 방법으로 저장되며 인덱스 특별히으로 기억됩니다 op_array->this_var. $this사용이 발견 되지 않으면 이 값은에서 초기화되지 않은 상태로 유지 -1됩니다. 새로운 실행 컨텍스트를 VM 스택에 푸시 할 때 PHP는 확인 op_array->this_var하고 그렇지 않은 경우 변수 항목을 -1초기화합니다 $this.

변수 변수에 액세스하면 PHP는 CV 테이블을 살펴보고 여기에서 적절한 기호 해시 테이블을 구성합니다. 물론 실제로 CV 테이블에있는 변수 만 추가하므로 포함 $this되지 않은 경우 정의되지 않은 변수 조회가 발생합니다.

이제 세 가지 경우를 고려하십시오.

  1. $this${"this"}같이 동일까지 (변수 이름이 두 경우 모두에서 컴파일 타임에 알려진 모든 후) PHP 컴파일러에 관한 한.
  2. PHP 5.x 컴파일러는 아직 상수 표현식 폴딩을 수행하지 않기 ${"th"."is"}때문에 $this액세스 인 것도 감지 할 수 없습니다 . 따라서 this_var초기화되지 않은 상태로 유지됩니다.
  3. 마지막 경우 에는 변수 변수 조회를 통해 설정되고 액세스 할 수 있는 일반 $this사용법 this_var이 있습니다.

PHP 7에서는 상황이 다릅니다. 항상 this_var변수 변수 조회를 설정하므로 간접 $this조회는 항상 작동해야합니다.

참조 URL : https://stackoverflow.com/questions/28419924/dynamically-reference-to-this-should-not-work-but-it-does

반응형