Шансы на нахождения подобного плагина с нормальным функционалом минимальны. Для определения ошибочности слов нужен неслабый словарик и достаточное количество матана.
Нефиг обижать БАДы. Любые витамины идут с припиской "БАД", а не "лекарство". Никому в голову не придёт проплачивать исследования и лицухи каждые n лет доказывая, что "витамин C" не начнёт вызывать раковые опухоли или выкидыши у беременных.
И да, спорящие в этом унылом и адом забытом топике вообще в курсе что такое "БАД" и чем он отличается от лекарств? Или тут отряд балаболов, которые не способны отличить курок от спускового крючка, но зато впереди планеты всей со своим мнением о том, в чём ни сантиметра не понимают?
https://support.google.com/webmasters/answer/1211158?hl=ru
https://support.google.com/webmasters/answer/99170?hl=ru&ref_topic=1088472
Поддерживается только ImageObject.
Упрт. Реально упрт.
ZXreader пока самый вменяемый как под симбу, так и под ведро. Жаль только интерфейс на параноика и икон-сет кривоватый, долго соображаешь что может обозначать эта картинка.
Определитесь, что вам нужно. И желательно с пояснением чем не устраивает рваный массив.
Шутка про телепатов в отпуске должна быть запощена сейчас. А, вот и уже.
Примеры использования в студию.
Можно заюзать `array_filter($array)` для чистки при том условии, что ТС'y не нужно оставлять в массиве значения нуля, false, null, "", "0", 0.0 и прочих эквивалентов булевой лжи помимо пустого подмассива.
При особой извращённой любви к пыху можно сделать что-нибудь вроде этого.
Да так-то переборы всё равно есть.
static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_compare_type, int key_compare_type) /* {{{ */{ zval ***args = NULL; HashTable *hash; int arr_argc, i, c; Bucket ***lists, **list, ***ptrs, *p; int 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, *fci_data; zend_fcall_info_cache *fci_key_cache, *fci_data_cache; PHP_ARRAY_CMP_FUNC_VARS; int (*diff_key_compare_func)(const void *, const void * TSRMLS_DC); int (*diff_data_compare_func)(const void *, const void * TSRMLS_DC); if (behavior == DIFF_NORMAL) { diff_key_compare_func = php_array_key_compare; if (data_compare_type == DIFF_COMP_DATA_INTERNAL) { /* array_diff */ req_args = 2; param_spec = "+"; diff_data_compare_func = php_array_data_compare; } else if (data_compare_type == DIFF_COMP_DATA_USER) { /* array_udiff */ req_args = 3; param_spec = "+f"; diff_data_compare_func = php_array_user_compare; } else { php_error_docref(NULL TSRMLS_CC, 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 TSRMLS_CC, E_WARNING, "at least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS()); return; } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, param_spec, &args, &arr_argc, &fci1, &fci1_cache) == FAILURE) { return; } fci_data = &fci1; fci_data_cache = &fci1_cache; } else if (behavior & DIFF_ASSOC) { /* triggered also if DIFF_KEY */ /* DIFF_KEY is subset of DIFF_ASSOC. When having the former * no comparison of the data is done (part of DIFF_ASSOC) */ if (data_compare_type == DIFF_COMP_DATA_INTERNAL && key_compare_type == DIFF_COMP_KEY_INTERNAL) { /* array_diff_assoc() or array_diff_key() */ req_args = 2; param_spec = "+"; diff_key_compare_func = php_array_key_compare; diff_data_compare_func = php_array_data_compare; } else if (data_compare_type == DIFF_COMP_DATA_USER && key_compare_type == DIFF_COMP_KEY_INTERNAL) { /* array_udiff_assoc() */ req_args = 3; param_spec = "+f"; diff_key_compare_func = php_array_key_compare; diff_data_compare_func = php_array_user_compare; fci_data = &fci1; fci_data_cache = &fci1_cache; } else if (data_compare_type == DIFF_COMP_DATA_INTERNAL && key_compare_type == DIFF_COMP_KEY_USER) { /* array_diff_uassoc() or array_diff_ukey() */ req_args = 3; param_spec = "+f"; diff_key_compare_func = php_array_user_key_compare; diff_data_compare_func = php_array_data_compare; fci_key = &fci1; fci_key_cache = &fci1_cache; } else if (data_compare_type == DIFF_COMP_DATA_USER && key_compare_type == DIFF_COMP_KEY_USER) { /* array_udiff_uassoc() */ req_args = 4; param_spec = "+ff"; diff_key_compare_func = php_array_user_key_compare; diff_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 TSRMLS_CC, 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 TSRMLS_CC, E_WARNING, "at least %d parameters are required, %d given", req_args, ZEND_NUM_ARGS()); return; } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, param_spec, &args, &arr_argc, &fci1, &fci1_cache, &fci2, &fci2_cache) == FAILURE) { return; } } else { php_error_docref(NULL TSRMLS_CC, 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); php_set_compare_func(PHP_SORT_STRING TSRMLS_CC); if (behavior == DIFF_NORMAL && data_compare_type == DIFF_COMP_DATA_USER) { BG(user_compare_fci) = *fci_data; BG(user_compare_fci_cache) = *fci_data_cache; } else if (behavior & DIFF_ASSOC && key_compare_type == DIFF_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_PP(args) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i + 1); arr_argc = i; /* only free up to i - 1 */ goto out; } hash = Z_ARRVAL_PP(args); list = (Bucket **) pemalloc((hash->nNumOfElements + 1) * sizeof(Bucket *), hash->persistent); if (!list) { PHP_ARRAY_CMP_FUNC_RESTORE(); efree(ptrs); efree(lists); efree(args); RETURN_FALSE; } lists = list; ptrs = list; for (p = hash->pListHead; p; p = p->pListNext) { *list++ = p; } *list = NULL; if (behavior == DIFF_NORMAL) { zend_qsort((void *) lists, hash->nNumOfElements, sizeof(Bucket *), diff_data_compare_func TSRMLS_CC); } else if (behavior & DIFF_ASSOC) { /* triggered also when DIFF_KEY */ zend_qsort((void *) lists, hash->nNumOfElements, sizeof(Bucket *), diff_key_compare_func TSRMLS_CC); } } /* copy the argument array */ RETVAL_ZVAL(*args[0], 1, 0); if (return_value->value.ht == &EG(symbol_table)) { HashTable *ht; zval *tmp; ALLOC_HASHTABLE(ht); zend_hash_init(ht, zend_hash_num_elements(return_value->value.ht), NULL, ZVAL_PTR_DTOR, 0); zend_hash_copy(ht, return_value->value.ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); return_value->value.ht = ht; } /* go through the lists and look for values of ptr[0] that are not in the others */ while (*ptrs[0]) { if ((behavior & DIFF_ASSOC) /* triggered also when DIFF_KEY */ && key_compare_type == DIFF_COMP_KEY_USER ) { BG(user_compare_fci) = *fci_key; BG(user_compare_fci_cache) = *fci_key_cache; } c = 1; for (i = 1; i < arr_argc; i++) { Bucket **ptr = ptrs; if (behavior == DIFF_NORMAL) { while (*ptrs && (0 < (c = diff_data_compare_func(ptrs[0], ptrs TSRMLS_CC)))) { ptrs++; } } else if (behavior & DIFF_ASSOC) { /* triggered also when DIFF_KEY */ while (*ptr && (0 != (c = diff_key_compare_func(ptrs[0], ptr TSRMLS_CC)))) { ptr++; } } if (!c) { if (behavior == DIFF_NORMAL) { if (*ptrs) { ptrs++; } break; } else if (behavior == DIFF_ASSOC) { /* only when DIFF_ASSOC */ /* In this branch is execute only when DIFF_ASSOC. If behavior == DIFF_KEY * data comparison is not needed - skipped. */ if (*ptr) { if (data_compare_type == DIFF_COMP_DATA_USER) { BG(user_compare_fci) = *fci_data; BG(user_compare_fci_cache) = *fci_data_cache; } if (diff_data_compare_func(ptrs[0], ptr TSRMLS_CC) != 0) { /* the data is not the same */ c = -1; if (key_compare_type == DIFF_COMP_KEY_USER) { BG(user_compare_fci) = *fci_key; BG(user_compare_fci_cache) = *fci_key_cache; } } else { break; /* we have found the element in other arrays thus we don't want it * in the return_value -> delete from there */ } } } else if (behavior == DIFF_KEY) { /* only when DIFF_KEY */ /* the behavior here differs from INTERSECT_KEY in php_intersect * since in the "diff" case we have to remove the entry from * return_value while when doing intersection the entry must not * be deleted. */ break; /* remove the key */ } } } if (!c) { /* ptrs[0] in one of the other arguments */ /* delete all entries with value as ptrs[0] */ for (;;) { p = *ptrs[0]; if (p->nKeyLength == 0) { zend_hash_index_del(Z_ARRVAL_P(return_value), p->h); } else { zend_hash_quick_del(Z_ARRVAL_P(return_value), p->arKey, p->nKeyLength, p->h); } if (!*++ptrs[0]) { goto out; } if (behavior == DIFF_NORMAL) { if (diff_data_compare_func(ptrs[0] - 1, ptrs[0] TSRMLS_CC)) { break; } } else if (behavior & DIFF_ASSOC) { /* triggered also when DIFF_KEY */ /* in this case no array_key_compare is needed */ break; } } } else { /* ptrs[0] in none of the other arguments */ /* skip all entries with value as ptrs[0] */ for (;;) { if (!*++ptrs[0]) { goto out; } if (behavior == DIFF_NORMAL) { if (diff_data_compare_func(ptrs[0] - 1, ptrs[0] TSRMLS_CC)) { break; } } else if (behavior & DIFF_ASSOC) { /* triggered also when DIFF_KEY */ /* in this case no array_key_compare is needed */ break; } } } }out: for (i = 0; i < arr_argc; i++) { hash = Z_ARRVAL_PP(args); pefree(lists, hash->persistent); } PHP_ARRAY_CMP_FUNC_RESTORE(); efree(ptrs); efree(lists); efree(args);}