1. 程式人生 > >數字索引陣列根據指定key轉關聯陣列

數字索引陣列根據指定key轉關聯陣列

array.c

PHP_FUNCTION(array_to_associative) {

    zval *array;

    char *key_name;

    uint key_len;

    HashPosition pos;

    zval **operand;

    char *string_key;

    uint string_key_len;

    zval **entry;

    uint data_type;

    ulong num_key;

    HashPosition data_pos;

    zval **data;

    zend_fcall_info fci = empty_fcall_info;

    zend_fcall_info_cache fci_cache = empty_fcall_info_cache;

    zend_bool have_callback = 0;

    zval *retval = NULL;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "as|f", &array, &key_name, &key_len, &fci, &fci_cache) == FAILURE) {

        return;

    }

    array_init(return_value);

    /*

                    array_init(retval);

     */

    if (ZEND_NUM_ARGS() > 2) {

        have_callback = 1;

        fci.no_separation = 0;

        fci.retval_ptr_ptr = &retval;

        fci.param_count = 1;

    }

    for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos);

            zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **) &operand, &pos) == SUCCESS;

            zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos)

            ) {

        zval_add_ref(operand);

        if (Z_TYPE_PP(operand) != IS_ARRAY) {

            php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred the second dimensional must be array!");

            return;

        }

        /*******callback*******/

        if (have_callback == 1) {

            fci.params = &operand;

            if (zend_call_function(&fci, &fci_cache TSRMLS_CC) != SUCCESS || !retval) {

                php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the associative callback");

                RETURN_NULL();

            }

        } else {

            retval = *operand;

        }

        for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(*operand), &data_pos);

                zend_hash_get_current_data_ex(Z_ARRVAL_P(*operand), (void **) &entry, &data_pos) == SUCCESS;

                zend_hash_move_forward_ex(Z_ARRVAL_P(*operand), &data_pos)

                ) {

            zval_add_ref(entry);

            zend_hash_get_current_key_ex(Z_ARRVAL_P(*operand), &string_key, &string_key_len, &num_key, 0, &data_pos);

            /*

                        php_printf("%s/n", string_key);

             */

            zend_hash_get_current_data_ex(Z_ARRVAL_P(*entry), (void **) &data, &data_pos);

            data_type = Z_TYPE_PP(data);

            /*

                        php_printf("%d/n", data_type);

             */

            if (strcmp(string_key, key_name) == 0) {

                switch (data_type) {

                    case IS_STRING:

                        /*

                                                php_printf("%s/n", Z_STRVAL_PP(data));

                         */

                        zend_hash_update(Z_ARRVAL_P(return_value), Z_STRVAL_PP(data), Z_STRLEN_PP(data) + 1, &retval, sizeof (zval *), NULL);

                        break;

                    case IS_LONG:

                        /*

                                                php_printf("%d/n", Z_LVAL_PP(data));

                         */

                        zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(data), &retval, sizeof (zval *), NULL);

                        break;

                    case IS_DOUBLE:

                        /*

                                                php_printf("%5.5f/n", Z_DVAL_PP(data));

                         */

                        zend_hash_index_update(Z_ARRVAL_P(return_value), Z_DVAL_PP(data), &retval, sizeof (zval *), NULL);

                        break;

                }

                break;

            }

        }

    }

}

basic_functions.c

PHP_FE(array_to_associative,arginfo_array_to_associative)

ZEND_BEGIN_ARG_INFO(arginfo_array_to_associative, 0)

ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */

ZEND_ARG_INFO(0, key_name)

ZEND_END_ARG_INFO()

php_array.h

PHP_FUNCTION(array_to_associative);