이 글은 PHP에 대한 관련 지식을 제공합니다. 주로 배열이 다양한 데이터 유형을 유연하게 지원할 수 있는 방법을 소개합니다. 관심 있는 친구는 아래를 살펴보는 것이 도움이 될 것입니다.
PHP에서는 배열 데이터 구조의 애플리케이션 처리가 매우 자주 사용됩니다. Java 및 C++와 같은 강력한 유형의 언어에 비해 PHP의 배열은 사용하기가 너무 쉽고 다양한 유형의 데이터를 저장할 수 있습니다. 데이터 유형(예: 숫자, 문자열, 객체 등)은 개발에 큰 편의성을 제공합니다.
PHP 배열의 강력한 기능을 기반으로 스택, 큐, 목록, 세트, 사전 등과 같은 보다 복잡한 데이터 구조를 쉽게 구현할 수 있습니다.
PHP가 배열을 어떻게 구현하는지 알고 싶으십니까?
PHP 배열은 HashTable 구조를 사용하여 내부적으로 구현되므로 먼저 HashTable에 대해 간단히 살펴보겠습니다!
HashTable이라고도 알려진 HashTable은 키-값을 통해 데이터에 효율적으로 접근하는 구조입니다. 해시 테이블은 배열과 연결 목록의 조합으로, 배열의 빠른 주소 지정과 연결 목록의 빠른 삽입을 통합합니다.
HashTable은 크게 두 개의 링크로 나누어집니다.
1. 해시 함수: 해시 함수는 찾으려는 값을 숫자 인덱스로 변환하며, 숫자 인덱스를 사용하면 값의 위치를 빠르게 찾을 수 있습니다.
2. 해시 충돌: 이상적으로는 서로 다른 값이 해시 함수를 통과한 후 결과가 달라집니다. 해싱 후 서로 다른 값이 동일한 숫자를 갖는 경우 이를 해시 충돌이라고 합니다.
그래서 HashTable을 적용할 때 해시 충돌 문제에 직면해야 합니다. 해결 방법에는 크게 연결 목록 방식과 개방형 주소 지정 방식이 있습니다.
zend_type.h 파일에서 다음과 같이 HashTable의 주요 구조 정의를 찾을 수 있습니다.
zend_array 유형
소개할 몇 가지 주요 멤버를 선택하세요.
gc: 참조 계산, 가비지 수집 사용 .
arData: 해시 테이블에 저장 요소를 저장하는 배열, 해당 메모리는 연속적이며 arData는 배열의 시작 위치를 가리킵니다.
nTableSize: 배열의 총 용량, 즉 수용할 수 있는 요소 수, arData의 메모리 크기는 이 값을 기준으로 결정되며 크기는 2의 거듭제곱이며 최소값은 8이며 이후 8, 16, 32...에 따라 순서대로 증가합니다. ;
Bucket 유형
Bucket 구조는 비교적 간단하며 주로 요소의 키와 값뿐만 아니라 정수 h(해시 값 또는 해시 값)를 저장하는 데 사용됩니다.
요소가 숫자 인덱스인 경우 해당 값은 숫자 인덱스의 값입니다.
문자열 인덱스인 경우 해당 값은 Time33 알고리즘을 통해 계산된 키의 해시 값입니다.
h 값은 궁극적으로 요소의 저장 위치를 매핑하는 데 사용됩니다.
위 부분에서 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의 의미를 자세히 설명합니다.
배열의 각 요소 순서는 삽입 순서와 일치합니다.
PHP 배열의 질서를 달성하기 위해 PHP의 기본 해시 테이블은 해시 함수와 요소 배열 사이에 매핑 테이블을 추가하며 이 매핑 테이블은 요소를 저장하는 배열과 동일한 크기를 갖습니다. 유형은 정수이며 실제 저장된 정렬 배열에 요소의 첨자를 저장하는 데 사용됩니다. 요소는 실제 저장된 배열에 순서대로 삽입된 다음 배열 첨자가 해시된 위치에 따라 새 위치에 저장됩니다. 추가된 매핑 테이블에서:
이렇게 하면 최종 저장된 데이터의 질서가 완성됩니다.
이 중간 매핑 테이블은 PHP 배열의 기본 구조에서 명시적으로 식별되지 않지만 arData와 함께 배치됩니다. 배열이 초기화되면 Bucket을 저장하는 데 사용되는 메모리뿐만 아니라 동일한 개수의 매핑도 할당됩니다. uint32_t 크기의 Space가 할당되며, 이 두 공간을 함께 할당한 후 arData를 요소 배열이 저장된 위치로 오프셋하고 이 중간 매핑 테이블을 arData를 통해 앞으로 접근할 수 있습니다.
PHP 배열의 특징은 값을 키 유형에 매핑하는 것입니다. 다른 언어와 달리 PHP 배열의 키는 문자열이 될 수 있으며 값은 모든 유형이 될 수 있습니다.
정기적인 추가, 삭제, 수정 및 검색 외에도 배열에는 복사, 병합, 삭제, 재설정 등의 다른 작업도 있습니다. 이러한 작업에 해당하는 코드는 zend_hash.c에 있습니다. 그것에 대해 배우십시오.
추천 학습: "PHP 비디오 튜토리얼"
위 내용은 PHP 배열이 다양한 데이터 유형을 유연하게 지원하는 방법에 대한 심층 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!