|
Массивы хранятся с использованием внутренних хэш-таблиц Zend, доступ к которым
может быть получен с помощью zend_hash_*() API. Для каждого создаваемого вами массива вам понадобится дескриптор новой
хэш таблицы, который хранится в члене ht контейнера zval.value.
Имеется API, предназначенный исключительно для создания массивов.
Для создания нового массива вы вызываете array_init().
zval *new_array;
MAKE_STD_ZVAL(new_array);
if(array_init(new_array) != SUCCESS)
{
// здесь обработка ошибок
} | Если array_init() не смогла создать новый массив, она возвращает
FAILURE. Для добавления в массив новых элементов вы можете использовать многочисленные
функции, в зависимости от того, что нужно сделать. В Таблицах 9.8, 9.9 и 9.10 описаны
эти функции. Все функции возвращают FAILURE при неудаче и SUCCESS при успешном выполнении.
Рисунок 34-3. Таблица 9.8. Zend's API для ассоциативных массивов
Примечание: Все функции в Таблице 9.8 работают с массивом "array" с ключом
"key". Строка ключа не должна находиться во внутренней памяти Zend;
она будет дублироваться API. |
Функция | Описание |
---|
add_assoc_long(zval *array, char *key, longn);() | Добавляет элемент типа long. |
add_assoc_unset(zval *array, char *key);() | Добавляет unset-элемент. |
add_assoc_bool(zval *array, char *key, int b);() |
Добавляет Булев элемент. |
add_assoc_resource(zval *array, char *key, int r);() | Добавляет ресурс к массиву. |
add_assoc_double(zval *array, char *key, double d);() |
Добавляет значение с плавающей точкой. |
add_assoc_string(zval *array, char *key, char *str, int duplicate);() |
Добавляет строку к массиву. Флаг duplicate специфицирует, копируется ли содержимое строки во внутреннюю память Zend. |
add_assoc_stringl(zval *array, char *key, char *str, uint length, int duplicate);()
| Добавляет строку необходимого размера length к массиву. Иначе поведение как у
add_assoc_string()(). |
Рисунок 34-4. Таблица 9.9. Zend's API для индексированных массивов , Часть 1
Примечание: Все функции в Таблице 9.9 работают с массивом "array" с индексом
"idx". Индекс - всегда integer. |
Функция | Описание |
add_index_long(zval *array, uint idx, long n);() | Добавляет элемент типа long. |
add_index_unset(zval *array, uint idx);() | Добавляет unset-элемент. |
add_index_bool(zval *array, uint idx, int b);() | Добавляет Булев элемент. |
add_index_resource(zval *array, uint idx, int r);() |
Добавляет ресурс к массиву. |
add_index_double(zval *array, uint idx, double d);() | Добавляет значение с плавающей точкой. |
add_index_string(zval *array, uint idx, char *str, int duplicate);() |
Добавляет строку к массиву. Флаг duplicate специфицирует, копируется ли содержимое строки во внутреннюю память Zend. |
add_index_stringl(zval *array, uint idx, char *str, uint length, int duplicate);() |
Добавляет строку необходимого размера length к массиву. Эта функция работает быстрее и безопасна в бинарном режиме. Иначе
поведение как у add_index_string()(). |
Рисунок 34-5. Таблица 9.10. Zend's API для индексированных массивов , Часть 2
Примечание: Все функции в Таблице 9.10 работают с массивом "array".
Эти функции автоматически генерируют новый индекс на основе наибольшего
индекса, найденного в массиве. |
Функция | Описание |
add_next_index_long(zval *array, long n);() | Добавляет элемент типа long. |
add_next_index_unset(zval *array);() | Добавляет unset-элемент. |
add_next_index_bool(zval *array, int b);() | Добавляет Булев элемент. |
add_next_index_resource(zval *array, int r);() | Добавляет ресурс к массиву. |
add_next_index_double(zval *array, double d);() | Добавляет значение с плавающей точкой. |
add_next_index_string(zval *array, char *str, int duplicate);() |
Добавляет строку к массиву. Флаг duplicate специфицирует, копируется ли содержимое строки во внутреннюю память Zend. |
add_next_index_stringl(zval *array, char *str, uint length, int duplicate);() |
Добавляет строку необходимого размера length к массиву. Эта функция работает быстрее и безопасна в бинарном режиме. Иначе
поведение как у add_index_string()(). |
Все эти функции предоставляют удобную абстракцию API внутреннего хэша Zend.
Разумеется, вы можете также использовать функции хэша напрямую - например, если у вас уже есть размещённый
zval-контейнер, который вы хотите вставить в массив. Это делается с помощью
zend_hash_update()() для ассоциативный массивов (см. Листинг 9.12) и zend_hash_index_update()
- для индексированных массивов (см. Листинг 9.13): Рисунок 34-6. Листинг 9.12. Добавление элемента в ассоциативный массив.
zval *new_array, *new_element;
char *key = "element_key";
MAKE_STD_ZVAL(new_array);
MAKE_STD_ZVAL(new_element);
if(array_init(new_array) == FAILURE)
{
// здесь обработка ошибок
}
ZVAL_LONG(new_element, 10);
if(zend_hash_update(new_array->value.ht, key, strlen(key) + 1, (void *)&new_element, sizeof(zval *), NULL) == FAILURE)
{
// здесь обработка ошибок
} |
Рисунок 34-7. Листинг 9.13. Добавление элемента в индексированный массив.
zval *new_array, *new_element;
int key = 2;
MAKE_STD_ZVAL(new_array);
MAKE_STD_ZVAL(new_element);
if(array_init(new_array) == FAILURE)
{
// здесь обработка ошибок
}
ZVAL_LONG(new_element, 10);
if(zend_hash_index_update(new_array->value.ht, key, (void *)&new_element, sizeof(zval *), NULL) == FAILURE)
{
// здесь обработка ошибок
} |
Для эмуляции функциональности add_next_index_*() вы можете использовать:
zend_hash_next_index_insert(ht, zval **new_element, sizeof(zval *), NULL) |
- Примечание: для возвращения массивов из функций используйте array_init() и все
последующие акции с предопределённой переменной return_value (заданной в качестве аргумента
в вашей экспортируемой функции; см. ранее обсуждение интерфейса вызова). Вы не должны использовать при этом
MAKE_STD_ZVAL.
Подсказка: чтобы исключить необходимость каждый раз записывать
new_array->value.ht, вы можете использовать HASH_OF(new_array), что рекомендуется
также по соображениям стиля и обеспечения совместимости. | |