2017-01-21 3 views
1

erhalten Sie die Zeile bei diesem Offset, aber gibt es trotzdem zu wissen, welcher Offset der Ergebnissatz ist derzeit?PHP mysqli_result aktuelle Position

Einfache Abbildung ....

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

Während mit einem einfachen Zähler Klebrigkeit des oben zu halten ist einfach, in komplexeren Zurückspulen und fastforwarding sceanrios es ein Schmerz wird. Die implementations I've seen from years ago schrieb Erweiterungsklassen, die einen manullay created counter sicherten, wurde inkrementiert, egal was der -> fetch_ * (oder data_seek) Aufruf verwendet wurde. Ist das immer noch die einzige Option?

EDIT

Ich habe es auf mich genommen, dies zu prüfen, indem die mysqli-Erweiterung which is on github Forking Aber ich bin ein totaler Anfänger mit C und PHP-Erweiterung Entwicklung. Hier ist mein erster Eindruck.

Die mysqli_result_iterator.c definiert den internen Zeiger als 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. Dass ich Datei, die es sieht aus wie ich eine Methode hinzufügen müssen ...

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; 
} 

und fügen Sie diese Funktion auf die zend defs am Ende der Datei, wie zu jagen

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 
}; 

Der Versuch, die mysqli_result_iterator wird verwendet, ich in der mysqli.c finden es wie so implementiert ist ...

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); 

Allerdings kann ich nicht überall finden, wo der Iterator immer mit lernen interagierten ist.

mir sagen, wenn ich hier auf dem richtigen Weg bin ... von mysqli_nonapi.c FETCH_ALL Methodendefinition verwendet, die wie folgt

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); 

sieht}

Meine Vermutung wäre ich tun muss so etwas wie

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

Fügen Sie einen Zähler zur while hinzu – RiggsFolly

+0

In komplexen Rückspulen und schnellen Forwarding, ich würde lieber nicht ständig meinen eigenen Zähler verfolgen. – user2782001

+0

Sie haben _complex rewinding und fast forwarding nicht erwähnt, _ – RiggsFolly

Antwort

0

Schnell soloution:

$counter = 0; 

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

es scheint, als ob Leute, die dies zuvor benötigt haben, Klassenerweiterungen geschrieben haben, um sicherzustellen, dass der Zähler immer mit mysqli_result-> fetch_ * Aufrufen erhöht wird ... aber die Ergebnismenge hat ein interner Zeiger, also warum stellt PHP es nicht aus? – user2782001

+1

@ user2782001 Weil ich in 20 Jahren nie wirklich wissen musste, wo ich in einer Ergebnismenge war. Können Sie Ihre Anforderung beschreiben, warum müssen Sie wissen, welche Zeile Sie verarbeiten und warum müssen Sie innerhalb der Ergebnismenge springen – RiggsFolly

Verwandte Themen