PHP函数array_intersect_ukey
生活随笔
收集整理的這篇文章主要介紹了
PHP函数array_intersect_ukey
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
array_intersect_ukey通過(guò)自定義函數(shù)來(lái)比較鍵,計(jì)算數(shù)組的交集。
/*** Computes the intersection of arrays using a callback function on the keys for comparison* @link https://php.net/manual/en/function.array-intersect-ukey.php* @param array $array1 <p>* Initial array for comparison of the arrays.* </p>* @param array $array2 <p>* First array to compare keys against.* </p>* @param array $_ [optional]* @param callback $key_compare_func <p>* User supplied callback function to do the comparison.* </p>* @return array the values of array1 whose keys exist* in all the arguments.* @meta*/ function array_intersect_ukey(array $array1, array $array2, array $_ = null, $key_compare_func) { }示例:?
$array1 = ['a1' => 'aaa','b' => 'bbb','c1' => 'ccc' ];$array2 = ['a2' => 'aaa','b' => 'bbb2','c2' => 'ccc' ];$result = array_intersect_ukey($array1, $array2, function($k1, $k2){//echo $k1.'--'.$k2."\n";if ($k1 == $k2) {return 0;} elseif ($k1 < $k2) {return -1;} else {return 1;} });var_dump($result);//結(jié)果 //array(1) { // 'b' => // string(3) "bbb" //}php7.4.8 數(shù)組函數(shù) array_intersect_ukey實(shí)現(xiàn)源碼
PHP_FUNCTION(array_intersect_ukey) {php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_KEY, INTERSECT_COMP_DATA_INTERNAL, INTERSECT_COMP_KEY_USER); }?php_array_intersect函數(shù)
static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_compare_type, int key_compare_type) /* {{{ */ {zval *args = NULL;HashTable *hash;int arr_argc, i, c = 0;uint32_t idx;Bucket **lists, *list, **ptrs, *p;uint32_t req_args;char *param_spec;zend_fcall_info fci1, fci2;zend_fcall_info_cache fci1_cache = empty_fcall_info_cache, fci2_cache = empty_fcall_info_cache;zend_fcall_info *fci_key = NULL, *fci_data;zend_fcall_info_cache *fci_key_cache = NULL, *fci_data_cache;PHP_ARRAY_CMP_FUNC_VARS;int (*intersect_key_compare_func)(const void *, const void *);int (*intersect_data_compare_func)(const void *, const void *);if (behavior == INTERSECT_NORMAL) {intersect_key_compare_func = php_array_key_compare_string;if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL) {/* array_intersect() */req_args = 2;param_spec = "+";intersect_data_compare_func = php_array_data_compare_string;} else if (data_compare_type == INTERSECT_COMP_DATA_USER) {/* array_uintersect() */req_args = 3;param_spec = "+f";intersect_data_compare_func = php_array_user_compare;} else {php_error_docref(NULL, E_WARNING, "data_compare_type is %d. This should never happen. Please report as a bug", data_compare_type);return;}if (ZEND_NUM_ARGS() < req_args) {php_error_docref(NULL, E_WARNING, "at least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS());return;}if (zend_parse_parameters(ZEND_NUM_ARGS(), param_spec, &args, &arr_argc, &fci1, &fci1_cache) == FAILURE) {return;}fci_data = &fci1;fci_data_cache = &fci1_cache;} else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY *//* INTERSECT_KEY is subset of INTERSECT_ASSOC. When having the former* no comparison of the data is done (part of INTERSECT_ASSOC) */if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL && key_compare_type == INTERSECT_COMP_KEY_INTERNAL) {/* array_intersect_assoc() or array_intersect_key() */req_args = 2;param_spec = "+";intersect_key_compare_func = php_array_key_compare_string;intersect_data_compare_func = php_array_data_compare_string;} else if (data_compare_type == INTERSECT_COMP_DATA_USER && key_compare_type == INTERSECT_COMP_KEY_INTERNAL) {/* array_uintersect_assoc() */req_args = 3;param_spec = "+f";intersect_key_compare_func = php_array_key_compare_string;intersect_data_compare_func = php_array_user_compare;fci_data = &fci1;fci_data_cache = &fci1_cache;} else if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL && key_compare_type == INTERSECT_COMP_KEY_USER) {/* array_intersect_uassoc() or array_intersect_ukey() */req_args = 3;param_spec = "+f";intersect_key_compare_func = php_array_user_key_compare;intersect_data_compare_func = php_array_data_compare_string;fci_key = &fci1;fci_key_cache = &fci1_cache;} else if (data_compare_type == INTERSECT_COMP_DATA_USER && key_compare_type == INTERSECT_COMP_KEY_USER) {/* array_uintersect_uassoc() */req_args = 4;param_spec = "+ff";intersect_key_compare_func = php_array_user_key_compare;intersect_data_compare_func = php_array_user_compare;fci_data = &fci1;fci_data_cache = &fci1_cache;fci_key = &fci2;fci_key_cache = &fci2_cache;} else {php_error_docref(NULL, E_WARNING, "data_compare_type is %d. key_compare_type is %d. This should never happen. Please report as a bug", data_compare_type, key_compare_type);return;}if (ZEND_NUM_ARGS() < req_args) {php_error_docref(NULL, E_WARNING, "at least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS());return;}if (zend_parse_parameters(ZEND_NUM_ARGS(), param_spec, &args, &arr_argc, &fci1, &fci1_cache, &fci2, &fci2_cache) == FAILURE) {return;}} else {php_error_docref(NULL, E_WARNING, "behavior is %d. This should never happen. Please report as a bug", behavior);return;}PHP_ARRAY_CMP_FUNC_BACKUP();/* for each argument, create and sort list with pointers to the hash buckets */lists = (Bucket **)safe_emalloc(arr_argc, sizeof(Bucket *), 0);ptrs = (Bucket **)safe_emalloc(arr_argc, sizeof(Bucket *), 0);if (behavior == INTERSECT_NORMAL && data_compare_type == INTERSECT_COMP_DATA_USER) {BG(user_compare_fci) = *fci_data;BG(user_compare_fci_cache) = *fci_data_cache;} else if (behavior & INTERSECT_ASSOC && key_compare_type == INTERSECT_COMP_KEY_USER) {BG(user_compare_fci) = *fci_key;BG(user_compare_fci_cache) = *fci_key_cache;}for (i = 0; i < arr_argc; i++) {if (Z_TYPE(args[i]) != IS_ARRAY) {php_error_docref(NULL, E_WARNING, "Expected parameter %d to be an array, %s given", i + 1, zend_zval_type_name(&args[i]));arr_argc = i; /* only free up to i - 1 */goto out;}hash = Z_ARRVAL(args[i]);list = (Bucket *) pemalloc((hash->nNumOfElements + 1) * sizeof(Bucket), GC_FLAGS(hash) & IS_ARRAY_PERSISTENT);lists[i] = list;ptrs[i] = list;for (idx = 0; idx < hash->nNumUsed; idx++) {p = hash->arData + idx;if (Z_TYPE(p->val) == IS_UNDEF) continue;*list++ = *p;}ZVAL_UNDEF(&list->val);if (hash->nNumOfElements > 1) {if (behavior == INTERSECT_NORMAL) {zend_sort((void *) lists[i], hash->nNumOfElements,sizeof(Bucket), intersect_data_compare_func, (swap_func_t)zend_hash_bucket_swap);} else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY */zend_sort((void *) lists[i], hash->nNumOfElements,sizeof(Bucket), intersect_key_compare_func, (swap_func_t)zend_hash_bucket_swap);}}}/* copy the argument array */RETVAL_ARR(zend_array_dup(Z_ARRVAL(args[0])));/* go through the lists and look for common values */while (Z_TYPE(ptrs[0]->val) != IS_UNDEF) {if ((behavior & INTERSECT_ASSOC) /* triggered also when INTERSECT_KEY */&& key_compare_type == INTERSECT_COMP_KEY_USER) {BG(user_compare_fci) = *fci_key;BG(user_compare_fci_cache) = *fci_key_cache;}for (i = 1; i < arr_argc; i++) {if (behavior & INTERSECT_NORMAL) {while (Z_TYPE(ptrs[i]->val) != IS_UNDEF && (0 < (c = intersect_data_compare_func(ptrs[0], ptrs[i])))) {ptrs[i]++;}} else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY */while (Z_TYPE(ptrs[i]->val) != IS_UNDEF && (0 < (c = intersect_key_compare_func(ptrs[0], ptrs[i])))) {ptrs[i]++;}if ((!c && Z_TYPE(ptrs[i]->val) != IS_UNDEF) && (behavior == INTERSECT_ASSOC)) { /* only when INTERSECT_ASSOC *//* this means that ptrs[i] is not NULL so we can compare* and "c==0" is from last operation* in this branch of code we enter only when INTERSECT_ASSOC* since when we have INTERSECT_KEY compare of data is not wanted. */if (data_compare_type == INTERSECT_COMP_DATA_USER) {BG(user_compare_fci) = *fci_data;BG(user_compare_fci_cache) = *fci_data_cache;}if (intersect_data_compare_func(ptrs[0], ptrs[i]) != 0) {c = 1;if (key_compare_type == INTERSECT_COMP_KEY_USER) {BG(user_compare_fci) = *fci_key;BG(user_compare_fci_cache) = *fci_key_cache;/* When KEY_USER, the last parameter is always the callback */}/* we are going to the break */} else {/* continue looping */}}}if (Z_TYPE(ptrs[i]->val) == IS_UNDEF) {/* delete any values corresponding to remains of ptrs[0] *//* and exit because they do not present in at least one of *//* the other arguments */for (;;) {p = ptrs[0]++;if (Z_TYPE(p->val) == IS_UNDEF) {goto out;}if (p->key == NULL) {zend_hash_index_del(Z_ARRVAL_P(return_value), p->h);} else {zend_hash_del(Z_ARRVAL_P(return_value), p->key);}}}if (c) /* here we get if not all are equal */break;ptrs[i]++;}if (c) {/* Value of ptrs[0] not in all arguments, delete all entries *//* with value < value of ptrs[i] */for (;;) {p = ptrs[0];if (p->key == NULL) {zend_hash_index_del(Z_ARRVAL_P(return_value), p->h);} else {zend_hash_del(Z_ARRVAL_P(return_value), p->key);}if (Z_TYPE((++ptrs[0])->val) == IS_UNDEF) {goto out;}if (behavior == INTERSECT_NORMAL) {if (0 <= intersect_data_compare_func(ptrs[0], ptrs[i])) {break;}} else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY *//* no need of looping because indexes are unique */break;}}} else {/* ptrs[0] is present in all the arguments *//* Skip all entries with same value as ptrs[0] */for (;;) {if (Z_TYPE((++ptrs[0])->val) == IS_UNDEF) {goto out;}if (behavior == INTERSECT_NORMAL) {if (intersect_data_compare_func(ptrs[0] - 1, ptrs[0])) {break;}} else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY *//* no need of looping because indexes are unique */break;}}}} out:for (i = 0; i < arr_argc; i++) {hash = Z_ARRVAL(args[i]);pefree(lists[i], GC_FLAGS(hash) & IS_ARRAY_PERSISTENT);}PHP_ARRAY_CMP_FUNC_RESTORE();efree(ptrs);efree(lists); }php_array_user_key_compare函數(shù)?
static int php_array_user_key_compare(const void *a, const void *b) /* {{{ */ {Bucket *f;Bucket *s;zval args[2];zval retval;zend_long result;f = (Bucket *) a;s = (Bucket *) b;if (f->key == NULL) {ZVAL_LONG(&args[0], f->h);} else {ZVAL_STR_COPY(&args[0], f->key);}if (s->key == NULL) {ZVAL_LONG(&args[1], s->h);} else {ZVAL_STR_COPY(&args[1], s->key);}BG(user_compare_fci).param_count = 2;BG(user_compare_fci).params = args;BG(user_compare_fci).retval = &retval;BG(user_compare_fci).no_separation = 0;if (zend_call_function(&BG(user_compare_fci), &BG(user_compare_fci_cache)) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {result = zval_get_long(&retval);zval_ptr_dtor(&retval);} else {result = 0;}zval_ptr_dtor(&args[0]);zval_ptr_dtor(&args[1]);return ZEND_NORMALIZE_BOOL(result); }總結(jié)
以上是生活随笔為你收集整理的PHP函数array_intersect_ukey的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python监控网页_【小白教程】Pyt
- 下一篇: Python安全攻防-从入门到入狱