2017-01-21 5 views
1
mysqli_result->data_seek($offset) 

получит строку в этом смещении, но все равно знать, какое смещение результирующего набора в данный момент включено?PHP mysqli_result получить текущую позицию

Простая иллюстрация ....

while($row=$result->fetch_assoc()){ 
     //what offset is $result on now? 
} 

Сохраняя липкость выше с помощью простого счетчика легко, в более сложном перемотке и fastforwarding sceanrios становится болью. implementations I've seen from years ago написал классы расширений, которые гарантировали, что счетчик, созданный manullay, был увеличен независимо от того, какой был использован вызов -> fetch_ * (или data_seek). Это единственный вариант?

EDIT

я взял на себя, чтобы смотреть на это по разветвлению Mysqli расширения which is on github Но я в общей сложности новичок в C и разработке расширений PHP. Вот мое первое впечатление.

mysqli_result_iterator.c определяет внутренний указатель как row_num

typedef struct { 
    zend_object_iterator intern; 
    mysqli_object *result; 
    zval current_row; 
    my_longlong row_num; //THIS IS WHAT WE WANT TO EXPOSE! 
} php_mysqli_result_iterator; 

SO. В том, что я подам это выглядит, как мне нужно, чтобы добавить метод ...

static long php_mysqli_result_iterator_row_num(zend_object_iterator *iter){ 
    php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter; 

    return iterator->row_num; 
} 

и добавить эту функцию в Зенд DEFS в конце этого файла

zend_object_iterator_funcs php_mysqli_result_iterator_funcs = { 
    php_mysqli_result_iterator_dtor, 
    php_mysqli_result_iterator_valid, 
    php_mysqli_result_iterator_current_data, 
    php_mysqli_result_iterator_current_key, 
    php_mysqli_result_iterator_move_forward, 
    php_mysqli_result_iterator_rewind, 

    //ADDING CURRENT ROW NUM RETURN 
    php_msqli_result_iterator_row_num, 
    NULL 
}; 

Попытка гоняться, как mysqli_result_iterator используется я нахожу в mysqli.c это реализуется как так ...

REGISTER_MYSQLI_CLASS_ENTRY("mysqli_result", mysqli_result_class_entry, mysqli_result_methods); 
ce = mysqli_result_class_entry; 

//HERE IS THE ITERATOR 
mysqli_result_class_entry->get_iterator = php_mysqli_result_get_iterator; 
mysqli_result_class_entry->iterator_funcs.funcs = &php_mysqli_result_iterator_funcs; 

zend_class_implements(mysqli_result_class_entry, 1, zend_ce_traversable); 

Однако я нигде не могу найти, где итератор всегда взаимодействовали с, чтобы учиться.

скажите мне, если я нахожусь на правильном пути здесь ... используя fetch_all определение метода из mysqli_nonapi.c, который выглядит, как это

PHP_FUNCTION(mysqli_fetch_all) 
{ 
MYSQL_RES *result; 
zval  *mysql_result; 
zend_long  mode = MYSQLND_FETCH_NUM; 

if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &mode) == FAILURE) { 
    return; 
} 
MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); 

if (!mode || (mode & ~MYSQLND_FETCH_BOTH)) { 
    php_error_docref(NULL, E_WARNING, "Mode can be only MYSQLI_FETCH_NUM, " 
        "MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH"); 
    RETURN_FALSE; 
} 

mysqlnd_fetch_all(result, mode, return_value); 

}

Мое предположение было бы мне нужно сделать что-то вроде

PHP_FUNCTION(mysqli_current_row_num) 
{ 
MYSQL_RES *result; 
zval  *mysql_result; 


if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|l", &mysql_result, mysqli_result_class_entry, &mode) == FAILURE) { 
    return; 
} 
//this loads the result into my local result variable as a reference?? 
MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); 

/*Now what : do I need to use the get_iterator like this..*/ 
return result->get_iterator()->row_num; 

/* do I need to use the entire iterator method name*/ 
    return result->php_mysqli_result_iterator_row_num(); 

} 
+2

Добавить счетчик в то время как – RiggsFolly

+0

В сложной перемотке и быстрой пересылке мне не нужно постоянно следить за своим счетчиком. – user2782001

+0

Вы не упомянули перекомпоновку _complex и быструю пересылку, _ – RiggsFolly

ответ

0

Быстрая soloution:

$counter = 0; 

while($row=$result->fetch_assoc()){ 
    $counter++; 
    // DO STUFF for actual $counter (offset); 
} 
+0

кажется, что люди, которым это нужно, прежде чем написали расширения класса, чтобы убедиться, что счетчик всегда увеличивается с помощью вызовов mysqli_result-> fetch_ * ... но набор результатов имеет внутренний указатель, так почему php не подвергает его воздействию? – user2782001

+1

@ user2782001 Потому что через 20 лет мне никогда не нужно было знать, где я был в наборе результатов. Можете ли вы описать свое требование, почему вам нужно знать, какую строку вы обрабатываете, и почему вам нужно прыгать в пределах набора результатов – RiggsFolly

Смежные вопросы