Элементы упорядочиваются одинаково после разделения массива на array_keys() и array_values ​​()?

Я просмотрел страницы руководства array_keys и array_values. Ни один из них ничего не сказал о том, соблюдают ли они порядок элементов исходного массива. Все они обещают, что они вернут все ключи или значения из исходного массива. Но можем ли мы быть абсолютно уверены, что порядок элементов будет точно таким же, как и у исходного массива? Какой бы массив он ни был?

Я спрашиваю об этом, потому что у меня есть это:

$record = array('name' => 'Lisa', 'age' => 16, 'gender' => 'female');

$fields = array_keys($record);
$values = array_values($record);

$sql = "INSERT INTO {$this -> table} (".implode(', ', $fields).") VALUES (".implode(', ', array_fill(0, count($fields), '?')).")";
$sth = $this -> dbh -> prepare($sql);
$sth -> execute($values);

Хотя я могу использовать именованные параметры, но это будет стоить немного больше кода, поэтому я предпочитаю этот способ, который требует, чтобы элементы $fields и $values ​​находились в соответствующих парах, предпочтительно они были бы в том же порядке, что и исходный массив $запись.

Любая идея?

Ответ 1

Да, они есть. Действительно, это не указано в руководстве, поэтому я имею в виду внутреннюю реализацию. Здесь образец для array_keys():

/* Go through input array and add keys to the return array */
    zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
    while (zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void **)&entry, &pos) == SUCCESS) {
        if (search_value != NULL) {
            is_equal_func(&res, search_value, *entry TSRMLS_CC);
            add_key = zval_is_true(&res);
        }

        if (add_key) {
            MAKE_STD_ZVAL(new_val);
            zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(input), new_val, &pos);
            zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
        }

        zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos);
    }

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