>백엔드 개발 >PHP 튜토리얼 >PHP 배열이 다양한 데이터 유형을 유연하게 지원하는 방법에 대한 심층 분석

PHP 배열이 다양한 데이터 유형을 유연하게 지원하는 방법에 대한 심층 분석

藏色散人
藏色散人앞으로
2023-03-25 15:31:441597검색

이 글은 PHP에 대한 관련 지식을 제공합니다. 주로 배열이 다양한 데이터 유형을 유연하게 지원할 수 있는 방법을 소개합니다. 관심 있는 친구는 아래를 살펴보는 것이 도움이 될 것입니다.

PHP 배열이 다양한 데이터 유형을 유연하게 지원하는 방법에 대한 심층 분석

PHP에서는 배열 데이터 구조의 애플리케이션 처리가 매우 자주 사용됩니다. Java 및 C++와 같은 강력한 유형의 언어에 비해 PHP의 배열은 사용하기가 너무 쉽고 다양한 유형의 데이터를 저장할 수 있습니다. 데이터 유형(예: 숫자, 문자열, 객체 등)은 개발에 큰 편의성을 제공합니다.

PHP 배열의 강력한 기능을 기반으로 스택, 큐, 목록, 세트, ​​사전 등과 같은 보다 복잡한 데이터 구조를 쉽게 구현할 수 있습니다.

PHP 배열이 다양한 데이터 유형을 유연하게 지원하는 방법에 대한 심층 분석

PHP가 배열을 어떻게 구현하는지 알고 싶으십니까?

1. PHP 배열의 기본 데이터 구조

PHP 배열은 HashTable 구조를 사용하여 내부적으로 구현되므로 먼저 HashTable에 대해 간단히 살펴보겠습니다!

HashTable이라고도 알려진 HashTable은 키-값을 통해 데이터에 효율적으로 접근하는 구조입니다. 해시 테이블은 배열과 연결 목록의 조합으로, 배열의 빠른 주소 지정과 연결 목록의 빠른 삽입을 통합합니다.

PHP 배열이 다양한 데이터 유형을 유연하게 지원하는 방법에 대한 심층 분석

HashTable은 크게 두 개의 링크로 나누어집니다.

1. 해시 함수: 해시 함수는 찾으려는 값을 숫자 인덱스로 변환하며, 숫자 인덱스를 사용하면 값의 위치를 ​​빠르게 찾을 수 있습니다.

2. 해시 충돌: 이상적으로는 서로 다른 값이 해시 함수를 통과한 후 결과가 달라집니다. 해싱 후 서로 다른 값이 동일한 숫자를 갖는 경우 이를 해시 충돌이라고 합니다.

그래서 HashTable을 적용할 때 해시 충돌 문제에 직면해야 합니다. 해결 방법에는 크게 연결 목록 방식과 개방형 주소 지정 방식이 있습니다.

zend_type.h 파일에서 다음과 같이 HashTable의 주요 구조 정의를 찾을 수 있습니다.

zend_array 유형

소개할 몇 가지 주요 멤버를 선택하세요.

  • gc: 참조 계산, 가비지 수집 사용 .

  • arData: 해시 테이블에 저장 요소를 저장하는 배열, 해당 메모리는 연속적이며 arData는 배열의 시작 위치를 가리킵니다.

  • nTableSize: 배열의 총 용량, 즉 수용할 수 있는 요소 수, arData의 메모리 크기는 이 값을 기준으로 결정되며 크기는 2의 거듭제곱이며 최소값은 8이며 이후 8, 16, 32...에 따라 순서대로 증가합니다. ;

PHP 배열이 다양한 데이터 유형을 유연하게 지원하는 방법에 대한 심층 분석

Bucket 유형

Bucket 구조는 비교적 간단하며 주로 요소의 키와 값뿐만 아니라 정수 h(해시 값 또는 해시 값)를 저장하는 데 사용됩니다.

  • 요소가 숫자 인덱스인 경우 해당 값은 숫자 인덱스의 값입니다.

  • 문자열 인덱스인 경우 해당 값은 Time33 알고리즘을 통해 계산된 키의 해시 값입니다.

h 값은 궁극적으로 요소의 저장 위치를 ​​매핑하는 데 사용됩니다.

2. PHP 배열의 기본 구현

위 부분에서 zend_array의 데이터 구조에 대해 배웠고, 배열의 초기화를 살펴보겠습니다.

배열의 초기화는 다음과 같습니다. 주로 HashTable 멤버 설정을 위해 arData의 메모리는 초기화 중에 즉시 할당되지 않습니다. arData의 메모리는 첫 번째 요소가 삽입된 후에 할당됩니다.

전체 해시 구조를 더 잘 이해하기 위해 이 구조를 설명하는 예를 들어보겠습니다.

$data = array(
    'hello' => 'haha',
    1       => 'me to'
    'world' => 'world', 
    2       => 2
);
unset($data[1]);

위의 해시 구조는 어떤 모습이어야 할까요? arData에 저장된 결과는 어떤 모습이어야 합니까?

그림을 그려서 보면 더 직관적입니다.

arData는 각 요소의 키와 값을 구체적으로 저장하는 데 사용되는 버킷 유형 포인터입니다. 데이터는 요소가 저장된 순서대로 저장됩니다. 삽입되므로 배열의 순서도 이에 의해 보장됩니다.

arData 배열의 각 요소는 그림에서 볼 수 있듯이 왼쪽의 음수는 해시 값을 모듈로한 값이고 오른쪽의 arData 인덱스는 -8이 충돌하는 경우 저장됩니다. 연결리스트의 헤드 요소가 저장됩니다.

arData[0]: key='hello', h=xx(특정 값), val = 'haha'

arData[1]: val은 type=IS_UNDEF의 zval입니다(설정 해제된 직후는 아님) 대신 IS_UNDEF로 설정됨)

arData[2]: key='world', h=xx(특정 값), val = 'world'

arData[3]: key=NULL, h=2 (해시 값 충돌이 발생할 수 있음), val = 2

….

위 예에서는 nNumUsed, nNumOfElements, arData의 의미를 자세히 설명합니다.

3. PHP 배열의 질서

배열의 각 요소 순서는 삽입 순서와 일치합니다.

PHP 배열의 질서를 달성하기 위해 PHP의 기본 해시 테이블은 해시 함수와 요소 배열 사이에 매핑 테이블을 추가하며 이 매핑 테이블은 요소를 저장하는 배열과 동일한 크기를 갖습니다. 유형은 정수이며 실제 저장된 정렬 배열에 요소의 첨자를 저장하는 데 사용됩니다. 요소는 실제 저장된 배열에 순서대로 삽입된 다음 배열 첨자가 해시된 위치에 따라 새 위치에 저장됩니다. 추가된 매핑 테이블에서:

이렇게 하면 최종 저장된 데이터의 질서가 완성됩니다.

이 중간 매핑 테이블은 PHP 배열의 기본 구조에서 명시적으로 식별되지 않지만 arData와 함께 배치됩니다. 배열이 초기화되면 Bucket을 저장하는 데 사용되는 메모리뿐만 아니라 동일한 개수의 매핑도 할당됩니다. uint32_t 크기의 Space가 할당되며, 이 두 공간을 함께 할당한 후 arData를 요소 배열이 저장된 위치로 오프셋하고 이 중간 매핑 테이블을 arData를 통해 앞으로 접근할 수 있습니다.

요약

PHP 배열의 특징은 값을 키 유형에 매핑하는 것입니다. 다른 언어와 달리 PHP 배열의 키는 문자열이 될 수 있으며 값은 모든 유형이 될 수 있습니다.

정기적인 추가, 삭제, 수정 및 검색 외에도 배열에는 복사, 병합, 삭제, 재설정 등의 다른 작업도 있습니다. 이러한 작업에 해당하는 코드는 zend_hash.c에 있습니다. 그것에 대해 배우십시오.

추천 학습: "PHP 비디오 튜토리얼"

위 내용은 PHP 배열이 다양한 데이터 유형을 유연하게 지원하는 방법에 대한 심층 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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