Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting the internal array pointer without iterating in PHP

Tags:

arrays

php

Is it possible to set PHP's internal array pointer without first iterating through the array. Take the following dummy code as example:

$array = range(1, 100);

// Represents the array key
$pointer = 66;

set_array_pointer($pointer, $array);

$nextValue = next($array); // Should return 68
like image 522
Peter Avatar asked Apr 19 '16 13:04

Peter


1 Answers

The solution LibertyPaul provided using ArrayIterator::seek seems to be the only way to make php set a pointer to a position within an array without initializing looping in userland. php will internally loop through the array to set the pointer, though, as you can read from the php source of ArrayIterator::seek():

/* {{{ proto void ArrayIterator::seek(int $position)
   Seek to position. */
SPL_METHOD(Array, seek)
{
    zend_long opos, position;
    zval *object = getThis();
    spl_array_object *intern = Z_SPLARRAY_P(object);
    HashTable *aht = spl_array_get_hash_table(intern);
    int result;

    if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &position) == FAILURE) {
        return;
    }

    if (!aht) {
        php_error_docref(NULL, E_NOTICE, "Array was modified outside object and is no longer an array");
        return;
    }

    opos = position;

    if (position >= 0) { /* negative values are not supported */
        spl_array_rewind(intern);
        result = SUCCESS;

        while (position-- > 0 && (result = spl_array_next(intern)) == SUCCESS);

        if (result == SUCCESS && zend_hash_has_more_elements_ex(aht, spl_array_get_pos_ptr(aht, intern)) == SUCCESS) {
            return; /* ok */
        }
    }
    zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0, "Seek position %pd is out of range", opos);
} /* }}} */

So it looks like there is no way to set an array-pointer to a certain position without looping through the array

like image 193
Jojo Avatar answered Oct 04 '22 20:10

Jojo