|  | 
 Arrays
    Arrays are stored using Zend's internal hash tables, which can be
    accessed using the zend_hash_*() API. For every
    array that you want to create, you need a new hash table handle,
    which will be stored in the ht member of the
    zval.value container.
    
    There's a whole API solely for the creation of arrays, which is extremely
    handy. To start a new array, you call
    array_init(). 
     array_init()| zval *new_array;
MAKE_STD_ZVAL(new_array);
array_init(new_array); | 
  always returns SUCCESS .
    
    To add new elements to the array, you can use numerous functions,
    depending on what you want to do. 
    表格 33-1,
    表格 33-2 and
    表格 33-3
    describe these functions. All functions return
    FAILURE on failure and
    SUCCESS on success.
    表格 33-1. Zend's API for Associative Arrays | Function | Description |  | add_assoc_long(zval *array, char *key, long n);() | Adds an element of type long. |  | add_assoc_unset(zval *array, char *key);() | Adds an unset element. |  | add_assoc_bool(zval *array, char *key, int b);() | Adds a Boolean element. |  | add_assoc_resource(zval *array, char *key, int r);() | Adds a resource to the array. |  | add_assoc_double(zval *array, char *key, double d);() | Adds a floating-point value. |  | add_assoc_string(zval *array, char *key, char *str, int duplicate);() | Adds a string to the array. The
         flag duplicate specifies whether the string contents have to be
         copied to Zend internal memory. |  | add_assoc_stringl(zval *array, char *key, char *str, uint length, int duplicate);
         () | Adds a string with the desired length length
         to the array. Otherwise, behaves like
         add_assoc_string(). |  | add_assoc_zval(zval *array, char *key, zval *value);() | Adds a zval to the array.  Useful for adding other arrays, objects, streams, etc... | 
表格 33-2. Zend's API for Indexed Arrays, Part 1 | Function | Description |  | add_index_long(zval *array, uint idx, long
          n);() | Adds an element of type long. |  | add_index_unset(zval *array, uint
          idx);() | Adds an unset element. |  | add_index_bool(zval *array, uint idx, int
          b);() | Adds a Boolean element. |  | add_index_resource(zval *array, uint idx, int
          r);() | Adds a resource to the array. |  | add_index_double(zval *array, uint idx, double
          d);() | Adds a floating-point value. |  | add_index_string(zval *array, uint idx, char
          *str, int duplicate);() | Adds a string to the array. The
         flag duplicate specifies whether the string contents have to be
         copied to Zend internal memory. |  | add_index_stringl(zval *array, uint idx, char
          *str, uint length, int duplicate);() | Adds a string with the desired
         length length to the array. This function is faster and binary-safe. Otherwise, behaves like add_index_string()(). |  | add_index_zval(zval *array, uint idx, zval *value);() | Adds a zval to the array.  Useful for adding other arrays, objects, streams, etc... | 
表格 33-3. Zend's API for Indexed Arrays, Part 2 | Function | Description |  | add_next_index_long(zval *array, long
          n);() | Adds an element of type long. |  | add_next_index_unset(zval
          *array);() | Adds an unset element. |  | add_next_index_bool(zval *array, int
          b);() | Adds a Boolean element. |  | add_next_index_resource(zval *array, int
          r);() | Adds a resource to the array. |  | add_next_index_double(zval *array, double
          d);() | Adds a floating-point value. |  | add_next_index_string(zval *array, char *str,
          int duplicate);() | Adds a string to the array. The
         flag duplicate specifies whether the string contents have to be
         copied to Zend internal memory. |  | add_next_index_stringl(zval *array, char *str,
          uint length, int duplicate);() | Adds a string with the desired
         length length to the array. This function is faster and binary-safe. Otherwise, behaves like add_index_string()(). |  | add_next_index_zval(zval *array, zval *value);() | Adds a zval to the array.  Useful for adding other arrays, objects, streams, etc... | 
    All these functions provide a handy abstraction to Zend's internal hash
    API. Of course, you can also use the hash functions directly - for example, if
    you already have a zval container allocated that you want to 
    insert into an array. This is done using zend_hash_update()()
    for associative arrays (see 例子 33-3) and 
    zend_hash_index_update() for indexed arrays 
    (see 例子 33-4): 
     | 例子 33-3. Adding an element to an associative array. | zval *new_array, *new_element;
char *key = "element_key";
      
MAKE_STD_ZVAL(new_array);
MAKE_STD_ZVAL(new_element);
array_init(new_array);
ZVAL_LONG(new_element, 10);
if(zend_hash_update(new_array->value.ht, key, strlen(key) + 1, (void *)&new_element, sizeof(zval *), NULL) == FAILURE)
{
    // do error handling here
} | 
 | 
 | 例子 33-4. Adding an element to an indexed array. | zval *new_array, *new_element;
int key = 2;
MAKE_STD_ZVAL(new_array);
MAKE_STD_ZVAL(new_element);
array_init(new_array);
ZVAL_LONG(new_element, 10);
if(zend_hash_index_update(new_array->value.ht, key, (void *)&new_element, sizeof(zval *), NULL) == FAILURE)
{
    // do error handling here
} | 
 | 
 
    To emulate the functionality of
    add_next_index_*(), you can use this:
    | zend_hash_next_index_insert(ht, zval **new_element, sizeof(zval *), NULL) | 
 
    Note: To return arrays from a function, use array_init() and
    all following actions on the predefined variable return_value
    (given as argument to your exported function; see the earlier discussion of the call interface). You do not have to use
    MAKE_STD_ZVAL on this.
    
    Tip: To avoid having to
    write new_array->value.ht every time, you can
    use HASH_OF(new_array), which is also recommended for
    compatibility and style reasons.
   
 |  |