PHP 8.1에는 다른 흥미로운 기능들도 많지만 그 중에 소소하게 귀찮음을 덜어줄 array_is_list() 함수가 생겼다. 이 함수는 배열이 리스트 형태로 되어있는지 검사한다. 예전에는 동일한 기능을 하는 함수를 직접 구현해야 했지만 이제 PHP 언어 자체에서 이 기능을 지원한다.
PHP 자체에서 지원해줌으로 생기는 이점은 크게 2가지다.
- 직접 구현함으로 생기는 귀찮음을 덜고 버그가 생길 가능성을 줄일 수 있다.
- array_is_list() 함수는 C 언어로 구현되어 있기 때문에 빠르다.
마지막은 벤치마크가 아닌 실제 사용에서는 체감되지 않을 것이다.
이 함수 사용에 주의해야 할 점은 배열 내부의 순서도 영향을 미친다는 점이다:
<?php $arr1 = [1,2,3,4]; $arr2 = [0 => 1, 2 => 2, 1 => 3]; var_dump(array_is_list($arr1)); var_dump(array_is_list($arr2));
위의 코드를 실행시키면 $arr1은 true, $arr2는 false가 나온다.
Zend/zend_hash.h 파일에 array_is_list() 함수의 원형인 zend_array_is_list()가 있다. 이 함수 내용을 보면 아래와 같이 FOREACH로 키가 순서대로 들어있는지 확인하기 때문에 내부 순서 또한 정렬되어야 한다:
static zend_always_inline bool zend_array_is_list(zend_array *array) { zend_long expected_idx = 0; zend_long num_idx; zend_string* str_idx; /* Empty arrays are lists */ if (zend_hash_num_elements(array) == 0) { return 1; } /* Packed arrays are lists */ if (HT_IS_PACKED(array) && HT_IS_WITHOUT_HOLES(array)) { return 1; } /* Check if the list could theoretically be repacked */ ZEND_HASH_FOREACH_KEY(array, num_idx, str_idx) { if (str_idx != NULL || num_idx != expected_idx++) { return 0; } } ZEND_HASH_FOREACH_END(); return 1; }
그러므로 정렬이 되어있지 않은 리스트에 array_is_list() 함수를 사용하려면 먼저 ksort() 함수로 다시 정렬하면 된다.