>  기사  >  백엔드 개발  >  PHP7 커널 참조에 대한 심층적인 이해

PHP7 커널 참조에 대한 심층적인 이해

藏色散人
藏色散人앞으로
2019-02-12 14:56:552291검색

이전에는 참조(REFERENCE)가 PHP5의 플래그라고 말했지만, PHP7 이후에는 이를 새로운 유형인 IS_REFERNCE로 바꿨습니다. 그러나 참조는 매우 일반적인 응용 프로그램이므로 이번 변경으로 인해 많은 변경이 이루어졌습니다. 그리고 PHP7을 개발할 때 가끔 이 유형을 처리하는 것을 소홀히 해서 버그가 많이 발생했습니다.

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); //解引用
     goto try_again;
     break;
}

자신만의 확장 기능을 작성하고 이 새로운 유형을 고려하는 것을 잊어버린 경우 문제를 일으킬 것입니다.

왜?

# 🎜🎜#그래서 이 새로운 유형은 많은 문제를 가져올 것이기 때문에 왜 참조를 사용하여 그냥 플래그만 쓰면 되지 않겠습니까?#🎜🎜 #한마디로 이렇게 해야 합니다. -_#

앞서 언급했듯이 Hashtable은 zval을 직접 저장하므로 어떻게 할 수 있습니까? 두 개의 zval이 기호 테이블에서 값을 공유합니까? 문자열과 같은 복합 유형에는 문제가 없습니다. zend_refcounted 구조에 플래그 비트를 추가하여 참조임을 나타낼 수도 있습니다. Change On Write이지만 PHP7에서는 IS_LONG과 같은 일부 유형이 zval에 직접 저장되지만 참조 유형에는 참조 계산이 필요하므로 IS_LONG 및 IS_REFERNCE인 zval을 어떻게 표현합니까? 이를 위해 다음과 같은 새로운 유형을 만들었습니다.

그림에 표시된 것처럼 참조는 IS_REFERNCE에 대한 새로운 유형인 zend_reference, zval, zval입니다. value.ref는 참조 카운트와 zval을 포함하는 zend_reference에 대한 포인터입니다. 참고용으로 zval.value.ref->val에 저장됩니다. , zend_reference를 가리키는 IS_REFERNCE 유형의 zval을 사용하고 이 zend_reference->val은 IS_LONG 유형의 zval입니다.

Change On Write# 🎜🎜##🎜🎜 #PHP7 커널 참조에 대한 심층적인 이해PHP는 참조 계산을 사용하여 간단한 가비지 수집을 수행합니다. 다음 코드를 고려하세요.

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

$ref와 $val은 동일한 zval에 대한 참조입니다. PHP5에서는 이 상황을 다음과 같이 표현했습니다. 참조 카운트가 2이고 참조 플래그가 1입니다. $val을 $copy(3행)에 복사할 때 $val의 카운트가 1보다 크다는 것을 발견했습니다. 참조, 따라서 쓰기 시 변경이 필요합니다. 즉, 따라서 이 zval을 복사해야 합니다.

PHP7에서는 상황이 훨씬 간단해집니다. 먼저 $ref(line 2)에 참조를 할당하면 IS_REFERNCE 유형이 생성됩니다. 이때 이를 참조하는 두 개의 변수, zend_reference 구조의 참조 카운트 zval.value.ref->gc.refcount는 2입니다.

다시 값이 $copy에 할당되면(3행) ), $val이 참조인 것으로 밝혀졌으므로 $copy는 문자열 값이 laruence인 zval인 zval.value.ref->val을 가리키고, 그 다음 zval 참조 횟수 + 1, 즉 zval이 됩니다. .value.ref->val.value.str.gc.refcount는 2입니다. 복사가 생성되지 않습니다. 이렇게 하면 문제가 매우 잘 해결됩니다. 1장에서 언급한 PHP5의 고전적인 문제는 다음과 같습니다. 예를 들어 이전 장의 문제를 PHP7에서 실행하면 다음과 같은 결과가 나옵니다.

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

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

추천: "

PHP 튜토리얼

"

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

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