Skip to content

Instantly share code, notes, and snippets.

@julp
Created December 21, 2012 15:52
Show Gist options
  • Select an option

  • Save julp/4353610 to your computer and use it in GitHub Desktop.

Select an option

Save julp/4353610 to your computer and use it in GitHub Desktop.
PHP function array_rand_value(array &input [, boolean unset, boolean reindex])
/* ext/standard/array.c */
/* {{{ proto mixed array_rand_value(array &input [, boolean unset, boolean reindex])
Return a random value in the array */
PHP_FUNCTION(array_rand_value)
{
zval *array, **entry;
zend_bool unset, reindex;
long i, randval;
int length;
HashPosition pos;
char *key = NULL;
unsigned int key_len = 0;
unsigned long index;
unset = reindex = 0; /* FALSE by default */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|bb", &array, &unset, &reindex) == FAILURE) {
return;
}
if (reindex && !unset) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter 'reindex' ignored: applied only when 'unset' is true");
}
if (0 == (length = zend_hash_num_elements(Z_ARRVAL_P(array)))) { /* Empty: NOP */
return;
}
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos);
randval = php_rand(TSRMLS_C);
RAND_RANGE(randval, 0, length - 1, PHP_RAND_MAX); /* [0; length[ */
for (i = 0; i < randval; i++) {
zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos);
}
if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **) &entry, &pos)) {
RETVAL_ZVAL(*entry, 1, 0);
if (unset) {
if (HASH_KEY_NON_EXISTANT != zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &key, &key_len, &index, 0, &pos)) {
if (key && Z_ARRVAL_P(array) == &EG(symbol_table)) {
zend_delete_global_variable(key, key_len - 1 TSRMLS_CC);
} else {
zend_hash_del_key_or_index(Z_ARRVAL_P(array), key, key_len, index, key ? HASH_DEL_KEY : HASH_DEL_INDEX);
}
} /* else */
if (reindex) {
unsigned int k = 0;
int should_rehash = 0;
Bucket *p = Z_ARRVAL_P(array)->pListHead;
while (p != NULL) {
if (p->nKeyLength == 0) {
if (p->h != k) {
p->h = k++;
should_rehash = 1;
} else {
k++;
}
}
p = p->pListNext;
}
Z_ARRVAL_P(array)->nNextFreeElement = k;
if (should_rehash) {
zend_hash_rehash(Z_ARRVAL_P(array));
}
}
}
} /* else */
zend_hash_internal_pointer_reset(Z_ARRVAL_P(array));
}
/* }}} */
/* ext/standard/basic_function.c */
static
ZEND_BEGIN_ARG_INFO_EX(arginfo_array_rand_value, 0, 0, 1)
ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */
ZEND_ARG_INFO(0, unset)
ZEND_ARG_INFO(0, reindex)
ZEND_END_ARG_INFO()
PHP_FE(array_rand_value, arginfo_array_rand_value)
/* ext/standard/php_array.h */
PHP_FUNCTION(array_rand_value);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment