Функции PHP current () и key (); несовместимо с сигнатурой функции - PullRequest
5 голосов
/ 09 августа 2011

Я заметил, что PHP current() и key() функции массива ( как и другие функции указателя массива ) принимают аргумент массива по ссылке:

смешанный текущий (массив & $ array )
Каждый массив имеет внутренний указатель на свой «текущий» элемент, который инициализируется впервый элемент, вставленный в массив.

После нескольких быстрых проверок выясняется, что и current(), и key() ( в отличие от других функций-указателей массива ) принимаютаргумент массива по значению, таким образом, не выдавая ошибку при передаче возвращаемого значения функции.

Я пришел к выводу, что это просто потому, что current() и key() не пытаются переместить указатель массива, ипоэтому не требуется передавать аргумент по ссылке ( или делать это каким-либо прозрачным, тихим, скрытным способом ).Однако это немного беспокоит меня.

Может кто-нибудь подтвердить, является ли это предполагаемой функциональностью?Я бы с радостью использовал его для захвата первого элемента / ключа возвращаемого массива, но кажется странным, что PHP допускает это, когда практически при любых других обстоятельствах возникает фатальная ошибка ( или предупреждение строгих стандартов )выдается для передачи значений параметру по ссылке.

Функция или ошибка?


Например:

error_reporting(-1);

function getArray(){
    return array('a', 'b', 'c');
}

var_dump( current(getArray()) );
var_dump( key(getArray())     );
var_dump( next(getArray())    );
var_dump( prev(getArray())    );
var_dump( reset(getArray())   );
var_dump( end(getArray())     );

Результаты:

string(1) "a"

int(0)

Strict standards: Only variables should be passed by reference ...
string(1) "b"

Strict standards: Only variables should be passed by reference ...
bool(false)

Strict standards: Only variables should be passed by reference ...
string(1) "a"

Strict standards: Only variables should be passed by reference ...
string(1) "c"

1 Ответ

2 голосов
/ 09 августа 2011

Это определенно особенность, и я бы не хотел жить без нее.

Теперь вопрос в том, правильна ли документация о &.

код

ток

PHP_FUNCTION(current)
{
    HashTable *array;
    zval **entry;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) {
        return;
    }

    if (zend_hash_get_current_data(array, (void **) &entry) == FAILURE) {
        RETURN_FALSE;
    }
    RETURN_ZVAL(*entry, 1, 0);
}

рядом

PHP_FUNCTION(next)
{
    HashTable *array;
    zval **entry;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) {
        return;
    }

    zend_hash_move_forward(array);

    if (return_value_used) {
        if (zend_hash_get_current_data(array, (void **) &entry) == FAILURE) {
            RETURN_FALSE;
        }

        RETURN_ZVAL(*entry, 1, 0);
    }
}

Заключение

Документы верны - в обоих случаях массив берется как ссылка.

Понятия не имею, почему при одном выдает ошибку, другой нет.

Кстати, ошибки выбрасываются в

  • Zend / zend_vm_def.h
  • Zend / zend_vm_execute.h
...