Профессиональное программирование на PHP

Страница 499 из 591


Основы создания расширений 517

char *match; char *key; int match_len; ulong index; HashTable *array;

if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "as",

&z_array, &match, &match_len) == FAILURE) {

return;

}

array_init(return_value); array = HASH_OF(z_array); zend_hash_internal_pointer_reset(array);

while(zend_hash_get_current_key(array, &key, &index, 0) == HASH_KEY_IS_STRING) {

if(!strncmp(key, match, match_len)) {

zend_hash_get_current_data(array, (void**)&data),• zval_add_ref(data) ;

add_assoc_zval(return value, key, *data);

}

zend_hash_move_forward(array);

}

}

В этой функции много нового материала. Манипуляцию zval сейчас можно проигнорировать, она будет рассматриваться позднее. Важной частью примера в настоящий момент является процесс итерации в массиве. Сначала с помощью макроса HASH_OF () обеспечивается доступ к внутренней хеш-таблице массива. Затем с помощью функции zend_hash_internal_pointer_reset () сбрасывается внутренний итератор хеш-таблицы. Этот процесс сродни вызову функции reset ($array) ; в РНР.

Затем с помощью функции zend_hash_get_current_key () получается текущий ключ массива. Функция принимает указатель HashTable, char ** для имени ключа и ulong * для индекса массива. Необходимо передавать оба указателя, поскольку РНР использует унифицированный тип для ассоциативных и индексных массивов, чтобы элемент можно было найти по индексу или по ключу. Если текущий ключ отсутствует (например, если итератор достиг конца массива), функция возвращает HASH_KEY_ NON_EXISTENT; в противном случае она возвращает либо HASH_KEY_IS_STRING, либо HASH_KEY_IS_LONG, в зависимости от того, является массив ассоциативным или индексным.

Аналогично, чтобы извлечь текущий элемент данных, используется функция zend_hash_get_current_data (), которая принимает указатель HashTable и zval * * для сохранения значения данных. Если элемент массива соответствует условиям для копирования, то счетчик ссылок zval увеличивается с помощью функции zval_add_ref (), и элемент вставляется в возвращаемый массив. Переход к следующему ключу реализуется с помощью функции zend_hash_move_f orward ().

Макросы преобразования типов и доступа к значениям

Как описывалось в главе 20, zval-переменные фактически состоят из примитивных типов данных С, представленных объединением zvalue_value:

typedef union _zvalue_value { long Ival;




  Hostland.Ru

 «Бесплатный хостинг Hostland.Su» © 2006