📄 array.c
字号:
*return_value = **max; zval_copy_ctor(return_value); efree(args); }}/* }}} */static int php_array_walk(HashTable *target_hash, zval **userdata TSRMLS_DC){ zval **args[3], /* Arguments to userland function */ *retval_ptr, /* Return value - unused */ *key; /* Entry key */ char *string_key; uint string_key_len; ulong num_key; HashPosition pos; /* Set up known arguments */ args[1] = &key; args[2] = userdata; zend_hash_internal_pointer_reset_ex(target_hash, &pos); /* Iterate through hash */ while (zend_hash_get_current_data_ex(target_hash, (void **)&args[0], &pos) == SUCCESS) { /* Allocate space for key */ MAKE_STD_ZVAL(key); /* Set up the key */ if (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, &pos) == HASH_KEY_IS_LONG) { Z_TYPE_P(key) = IS_LONG; Z_LVAL_P(key) = num_key; } else { ZVAL_STRINGL(key, string_key, string_key_len-1, 1); } /* Call the userland function */ if (call_user_function_ex(EG(function_table), NULL, *BG(array_walk_func_name), &retval_ptr, userdata ? 3 : 2, args, 0, NULL TSRMLS_CC) == SUCCESS) { zval_ptr_dtor(&retval_ptr); } else { char *func_name; if (zend_is_callable(*BG(array_walk_func_name), 0, &func_name)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", func_name); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", func_name); } efree(func_name); break; } zval_ptr_dtor(&key); zend_hash_move_forward_ex(target_hash, &pos); } return 0;}/* {{{ proto bool array_walk(array input, string funcname [, mixed userdata]) Apply a user function to every member of an array */PHP_FUNCTION(array_walk){ zval *array, *userdata = NULL, *tmp, **old_walk_func_name; HashTable *target_hash; old_walk_func_name = BG(array_walk_func_name); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|z", &array, &tmp, &userdata) == FAILURE) { return; } target_hash = HASH_OF(array); if (!target_hash) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); RETURN_FALSE; } if (Z_TYPE_P(tmp) != IS_ARRAY && Z_TYPE_P(tmp) != IS_STRING) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong syntax for function name"); RETURN_FALSE; } else { BG(array_walk_func_name) = &tmp; } php_array_walk(target_hash, userdata ? &userdata : NULL TSRMLS_CC); BG(array_walk_func_name) = old_walk_func_name; RETURN_TRUE;}/* }}} *//* void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) * 0 = return boolean * 1 = return key */static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior){ zval **value, /* value to check for */ **array, /* array to check in */ **strict, /* strict comparison or not */ **entry, /* pointer to array entry */ res; /* comparison result */ HashTable *target_hash; /* array hashtable */ HashPosition pos; /* hash iterator */ ulong num_key; uint str_key_len; char *string_key; int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function; if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict) == FAILURE) { WRONG_PARAM_COUNT; } if (Z_TYPE_PP(value) == IS_OBJECT) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong datatype for first argument"); RETURN_FALSE; } if (Z_TYPE_PP(array) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong datatype for second argument"); RETURN_FALSE; } if (ZEND_NUM_ARGS() == 3) { convert_to_boolean_ex(strict); if (Z_LVAL_PP(strict)) { is_equal_func = is_identical_function; } } target_hash = HASH_OF(*array); zend_hash_internal_pointer_reset_ex(target_hash, &pos); while (zend_hash_get_current_data_ex(target_hash, (void **)&entry, &pos) == SUCCESS) { is_equal_func(&res, *value, *entry TSRMLS_CC); if (Z_LVAL(res)) { if (behavior == 0) { RETURN_TRUE; } else { /* Return current key */ switch (zend_hash_get_current_key_ex(target_hash, &string_key, &str_key_len, &num_key, 0, &pos)) { case HASH_KEY_IS_STRING: RETURN_STRINGL(string_key, str_key_len-1, 1); break; case HASH_KEY_IS_LONG: RETURN_LONG(num_key); break; } } } zend_hash_move_forward_ex(target_hash, &pos); } RETURN_FALSE;}/* {{{ proto bool in_array(mixed needle, array haystack [, bool strict]) Checks if the given value exists in the array */PHP_FUNCTION(in_array){ php_search_array(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict]) Searches the array for a given value and returns the corresponding key if successful */PHP_FUNCTION(array_search){ php_search_array(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* }}} */static int php_valid_var_name(char *var_name){ int len, i; if (!var_name) return 0; len = strlen(var_name); if (!isalpha((int)((unsigned char *)var_name)[0]) && var_name[0] != '_') return 0; if (len > 1) { for (i=1; i<len; i++) { if (!isalnum((int)((unsigned char *)var_name)[i]) && var_name[i] != '_') { return 0; } } } return 1;}/* {{{ proto int extract(array var_array [, int extract_type [, string prefix]]) Imports variables into symbol table from an array */PHP_FUNCTION(extract){ zval **var_array, **z_extract_type, **prefix; zval **entry, *data; char *var_name; smart_str final_name = {0}; ulong num_key; uint var_name_len; int var_exists, extract_type, key_type, count = 0; int extract_refs = 0; HashPosition pos; switch (ZEND_NUM_ARGS()) { case 1: if (zend_get_parameters_ex(1, &var_array) == FAILURE) { WRONG_PARAM_COUNT; } extract_type = EXTR_OVERWRITE; break; case 2: if (zend_get_parameters_ex(2, &var_array, &z_extract_type) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long_ex(z_extract_type); extract_type = Z_LVAL_PP(z_extract_type); extract_refs = (extract_type & EXTR_REFS); extract_type &= 0xff; if (extract_type > EXTR_SKIP && extract_type <= EXTR_PREFIX_IF_EXISTS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Prefix expected to be specified"); return; } break; case 3: if (zend_get_parameters_ex(3, &var_array, &z_extract_type, &prefix) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long_ex(z_extract_type); extract_type = Z_LVAL_PP(z_extract_type); extract_refs = (extract_type & EXTR_REFS); extract_type &= 0xff; convert_to_string_ex(prefix); break; default: WRONG_PARAM_COUNT; break; } if (extract_type < EXTR_OVERWRITE || extract_type > EXTR_IF_EXISTS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown extract type"); return; } if (Z_TYPE_PP(var_array) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument should be an array"); return; } zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(var_array), &pos); while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(var_array), (void **)&entry, &pos) == SUCCESS) { key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(var_array), &var_name, &var_name_len, &num_key, 0, &pos); var_exists = 0; if (key_type == HASH_KEY_IS_STRING) { var_name_len--; var_exists = zend_hash_exists(EG(active_symbol_table), var_name, var_name_len + 1); } else if (extract_type == EXTR_PREFIX_ALL || extract_type == EXTR_PREFIX_INVALID) { smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); smart_str_appendc(&final_name, '_'); smart_str_append_long(&final_name, num_key); } else { zend_hash_move_forward_ex(Z_ARRVAL_PP(var_array), &pos); continue; } switch (extract_type) { case EXTR_IF_EXISTS: if (!var_exists) break; /* break omitted intentionally */ case EXTR_OVERWRITE: /* GLOBALS protection */ if (var_exists && !strcmp(var_name, "GLOBALS")) { break; } smart_str_appendl(&final_name, var_name, var_name_len); break; case EXTR_PREFIX_IF_EXISTS: if (var_exists) { smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); smart_str_appendc(&final_name, '_'); smart_str_appendl(&final_name, var_name, var_name_len); } break; case EXTR_PREFIX_SAME: if (!var_exists) smart_str_appendl(&final_name, var_name, var_name_len); /* break omitted intentionally */ case EXTR_PREFIX_ALL: if (final_name.len == 0 && var_name_len != 0) { smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); smart_str_appendc(&final_name, '_'); smart_str_appendl(&final_name, var_name, var_name_len); } break; case EXTR_PREFIX_INVALID: if (final_name.len == 0) { if (!php_valid_var_name(var_name)) { smart_str_appendl(&final_name, Z_STRVAL_PP(prefix), Z_STRLEN_PP(prefix)); smart_str_appendc(&final_name, '_'); smart_str_appendl(&final_name, var_name, var_name_len); } else smart_str_appendl(&final_name, var_name, var_name_len); } break; default: if (!var_exists) smart_str_appendl(&final_name, var_name, var_name_len); break; } if (final_name.len) { smart_str_0(&final_name); if (php_valid_var_name(final_name.c)) { if (extract_refs) { zval **orig_var; if (zend_hash_find(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) &orig_var) == SUCCESS) { SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); zval_add_ref(entry); zval_ptr_dtor(orig_var); *orig_var = *entry; } else { if ((*var_array)->refcount > 1) { SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); } else { (*entry)->is_ref = 1; } zval_add_ref(entry); zend_hash_update(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) entry, sizeof(zval *), NULL); } } else { MAKE_STD_ZVAL(data); *data = **entry; zval_copy_ctor(data); ZEND_SET_SYMBOL(EG(active_symbol_table), final_name.c, data); } count++; } final_name.len = 0; } zend_hash_move_forward_ex(Z_ARRVAL_PP(var_array), &pos); } smart_str_free(&final_name); RETURN_LONG(count);}/* }}} */static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_value, zval *entry){ zval **value_ptr, *value, *data; if (Z_TYPE_P(entry) == IS_STRING) { if (zend_hash_find(eg_active_symbol_table, Z_STRVAL_P(entry), Z_STRLEN_P(entry)+1, (void **)&value_ptr) != FAILURE) { value = *value_ptr; ALLOC_ZVAL(data); *data = *value; zval_copy_ctor(data); INIT_PZVAL(data); zend_hash_update(Z_ARRVAL_P(return_value), Z_STRVAL_P(entry), Z_STRLEN_P(entry)+1, &data, sizeof(zval *), NULL); } } else if (Z_TYPE_P(entry) == IS_ARRAY) { HashPosition pos; zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(entry), &pos); while (zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), (void**)&value_ptr, &pos) == SUCCESS) { value = *value_ptr; php_compact_var(eg_active_symbol_table, return_value, value); zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos); } }}/* {{{ proto array compact(mixed var_names [, mixed ...]) Creates a hash containing variables and their values */PHP_FUNCTION(compact){ zval ***args; /* function arguments array */ int i; args = (zval ***)safe_emalloc(sizeof(zval **), ZEND_NUM_ARGS(), 0); if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) { efree(args); WRONG_PARAM_COUNT; } array_init(return_value); for (i=0; i<ZEND_NUM_ARGS(); i++) { php_compact_var(EG(active_symbol_table), return_value, *args[i]); } efree(args);}/* }}} *//* {{{ proto array array_fill(int start_key, int num, mixed val) Create an array containing num elements starting with index start_key each initialized to val */PHP_FUNCTION(array_fill){ zval **start_key, **num, **val, *newval; long i; if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &start_key, &num, &val) == FAILURE) { WRONG_PARAM_COUNT; } switch (Z_TYPE_PP(start_key)) { case IS_STRING: case IS_LONG: case IS_DOUBLE: /* allocate an array for return */ array_init(return_value); if (PZVAL_IS_REF(*val)) { SEPARATE_ZVAL(val); } convert_to_long_ex(start_key); zval_add_ref(val); zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(start_key), val, sizeof(val), NULL); break; default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong data type for start key"); RETURN_FALSE; break; } convert_to_long_ex(num); i = Z_LVAL_PP(num) - 1; if (i < 0) { zend_hash_destroy(Z_ARRVAL_P(return_value)); efree(Z_ARRVAL_P(return_value)); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Number of elements must be positive"); RETURN_FALSE; } newval = *val; while (i--) {#ifndef ZEND_ENGINE_2 if (newval->refcount >= 62000) { MAKE_STD_ZVAL(newval); *newval = **val; zval_copy_ctor(newval); newval->refcount = 0; }#endif zval_add_ref(&newval); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &newval, sizeof(zval *), NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -