>  기사  >  백엔드 개발  >  PHP7 커널에 대한 자세한 설명 참조

PHP7 커널에 대한 자세한 설명 참조

Guanhui
Guanhui앞으로
2020-06-06 09:20:232556검색

PHP7 커널에 대한 자세한 설명 참조

Problem

Reference(REFERENCE)는 PHP5의 플래그였지만 PHP7 이후에는 이를 새로운 유형인 IS_REFERNCE로 변경했습니다. 그러나 참조는 매우 일반적인 응용 프로그램이므로 이 변경으로 인해 많은 변화가 발생했습니다. , 또한 우리가 PHP7 개발을 할 때 때때로 이 유형을 처리하는 것을 무시했기 때문에 많은 버그를 일으켰습니다.

가장 간단한 경우는 다양한 유형을 다루는 것입니다. 이제부터 우리는 이 새로운 유형을 더 많이 고려해야 합니다. PHP7에서는 다음 코드 형식이 매우 일반적이 되었습니다.

try_again:swtich (Z_TYPE_P(zv)) { case IS_TRING: break; case IS_ARRAY: break; ... case IS_REFERENCE: zv = Z_REFVAL_P(zv) //dereference goto try_again ; break;}

자신만의 확장 기능을 작성하고 이 새로운 유형을 고려하는 것을 잊었다면 문제가 발생할 것입니다.

왜?

이 새로운 유형은 많은 문제를 가져올 것이므로 왜 사용했습니까? 그냥 플래그를 사용하면 되지 않겠습니까?
한 문장 즉, 이렇게 해야 합니다. -_#
앞서 언급했듯이 Hashtable은 zval을 직접 저장하므로 심볼 테이블에서 어떻게 두 개의 zval을 사용할 수 있습니까? 값을 공유하시겠습니까? 문자열과 같은 복잡한 유형의 경우 여전히 가능합니다. 문제를 해결하기 위한 참조임을 나타내기 위해 zend_refcounted 구조에 플래그 비트를 추가할 수 있는 것 같습니다. 그러나 이 경우에도 복사본이 발생합니다. Change On Write로 인해 발생하지만 PHP7에서는 IS_LONG과 같은 일부 유형이 zval에 직접 저장되지만 참조 유형에는 참조 계산이 필요하므로 IS_LONG 및 IS_REFERNCE인 zval을 어떻게 나타낼 수 있습니까?
이런 이유로 , 우리는 다음과 같은 새로운 유형을 만들었습니다.
PHP7 커널에 대한 자세한 설명 참조그림에 표시된 대로 참조는 새로운 유형: zend_reference입니다. IS_REFERNCE 유형의 zval의 경우 zval.value.ref는 참조 카운트와 zval을 포함하는 zend_reference에 대한 포인터입니다. zval의 특정 값은 val의 zval.value.ref->에 저장됩니다.
IS_LONG의 참조에는 zend_reference를 가리키는 IS_REFERNCE 유형의 zval을 사용하고 이 zend_reference->val은 zval입니다. IS_LONG.

Change On Write

PHP는 간단한 가비지 수집을 위해 참조 계산을 사용합니다. 다음 코드를 고려하세요.

<?php1. $val = "laruence";2. $ref = &$val;3. $copy = $val;?>

$ref와 $val은 동일한 zval을 가리키는 참조입니다. 이 상황을 나타내기 위해 참조 플래그 비트는 1입니다. $val을 $copy에 복사할 때(라인 3) $val이 1보다 큰 개수를 갖는 참조이므로 쓰기 시 변경은 다음과 같습니다. 생성, 즉 분리입니다. 따라서 이 zval을 복사해야 합니다.
PHP7에서는 먼저 참조가 $ref(2번째 줄)에 할당되면 IS_REFERNCE 유형이 생성되고 그 다음에는 상황이 훨씬 간단해집니다. 현재 이를 참조하는 두 개의 변수가 있습니다. zend_reference 이 구조 zval.value.ref->gc.refcount의 참조 카운트는 2입니다. 이후에 값이 $copy(3행)에 할당되면 $ val은 참조이므로 $copy는 zval value.ref->val, 즉 문자열 값이 laruence인 zval을 가리키고 zval의 참조 횟수를 1만큼 늘립니다. 즉 zval.value.ref ->val.value.str.gc.refcount는 2입니다. 그리고 복사가 생성되지 않습니다.
이것은 이전 장에서 언급한 PHP5의 고전적인 문제를 해결합니다. 예를 들어, 이전 장의 문제를 PHP7에서 실행하면 됩니다. , 우리가 얻는 결과는 다음과 같습니다.

$ php-7.0/sapi/cli/php /tmp/1.phpUsed 0.00021380008539Used 0.00020173048281

복사가 발생하지 않으므로 성능 문제가 발생하지 않습니다.

추천 튜토리얼: "

PHP"

위 내용은 PHP7 커널에 대한 자세한 설명 참조의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 laruence.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제