PHP의 새로운 기능에 대한 작은 문제 탐색

高洛峰
풀어 주다: 2016-11-22 09:17:14
원래의
1056명이 탐색했습니다.

문제 원인

이틀 전 그룹 내 new 및 stdClass에 대한 질문이 있었습니다. 구체적인 성능은 다음과 같습니다.

<?php
$a = new stdClass;
$b = new $a;
var_dump($a, $b);
로그인 후 복사

이 코드는 올바르게 실행될 수 있습니다. 그리고 $a와 $b는 서로 다른 두 개의 빈 객체입니다. 새로운 $a 이전에 $a에 속성을 추가하고 값을 할당하더라도 $b는 항상 빈 개체입니다.

그래서 질문은: 왜 빈 객체가 new를 따를 수 있습니까? stdClass에 특별한 것이 있습니까?

실제 성능

사실 이는 약간의 검증을 통해 알 수 있습니다. 사실 이는 stdClass와는 아무런 관련이 없습니다. 예를 들어 new의 동작에 의해 완전히 결정됩니다. psysh에서 간단한 테스트를 수행해 보세요.

>>> $a = new Reflection;
=> Reflection {#174}
>>> $b = new $a;
=> Reflection {#177}
로그인 후 복사

여기서 stdClass와 동일하게 동작하는 Reflection 클래스의 새 인스턴스를 만들었습니다. 물론, 클래스를 사용자 정의할 수도 있습니다.

>>> class Test { public $foo = 1; }
=> null
>>> $a = new Test
=> Test {#178
     +foo: 1,
   }
>>> $a->foo = 2;
=> 2
>>> $b = new $a;
=> Test {#180
     +foo: 1,
   }
로그인 후 복사

이 예에서 $a의 속성을 변경해도 $b에 영향을 미치지 않는다는 것을 분명히 알 수 있습니다(PHP 키워드: clone에 대해서도 생각해 볼 수 있음). ).

이제 성능을 알았으므로 결론을 내릴 수도 있습니다. new 클래스의 객체를 통해 새로운 객체를 생성하는 것은 원래 객체의 클래스인 new와 동일합니다.

원인

그럼 어떤 종류의 PHP 구현으로 인해 이러한 동작이 발생합니까? 이 문제를 분석하기 위해 소스 코드부터 시작해 보겠습니다.

사실 소스 코드에서 zend_vm_def.h로 바로 가서 답을 찾을 수 있습니다. opcode ZEND_FETCH_CLASS에 대한 설명에서 다음을 볼 수 있습니다.

ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMPVAR|UNUSED|CV)
{
        ...
        if (OP2_TYPE == IS_CONST) {
            ...
        } else if (Z_TYPE_P(class_name) == IS_OBJECT) {
            Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name);
        } ...
        ...
}
로그인 후 복사

일부 간섭 제거 문맥에서 위 내용은 명확하게 설명을 제공합니다. 획득한 class_name이 객체인 경우 해당 클래스는 Z_OBJCE_P 매크로를 통해 검색됩니다. 그래서 위의 성능은 설명하기 쉽습니다.

그 자체로는 매우 간단한 질문이므로 복잡하게 생각할 필요가 없습니다. new의 구체적인 구현을 알고 싶다면 zend_compile.c 파일로 이동하여 zend_compile_new의 구현을 볼 수 있습니다.


관련 라벨:
php
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!