W3docs

PHP mysqli_use_result() — Set di Risultati Non Bufferizzati Spiegati

Scopri come mysqli_use_result() avvia un result set MySQL non bufferizzato, le differenze da mysqli_store_result() e quando usarlo.

Quando si esegue una SELECT in PHP con l'estensione mysqli, MySQL deve restituire le righe corrispondenti allo script. Esistono due modi per riceverle: bufferizzato (copia l'intero risultato nella memoria PHP in una sola volta) e non bufferizzato (lascia le righe sul server MySQL e le recupera una alla volta). La funzione mysqli_use_result() avvia la modalità non bufferizzata.

Questa guida spiega cosa fa mysqli_use_result(), come si differenzia dalla modalità bufferizzata predefinita, le regole da seguire quando la si utilizza e quando conviene davvero usarla.

Cosa fa mysqli_use_result()

mysqli_use_result() avvia il recupero di un set di risultati prodotto da una query, senza copiare le righe nella memoria PHP. Invece di scaricare tutte le righe in anticipo, il server mantiene le righe e lo script le recupera una per una durante il ciclo.

Confrontatelo con il comportamento predefinito. Quando si chiama mysqli_query(), mysqli internamente chiama mysqli_store_result() al posto vostro — recupera l'intero set di risultati nella memoria del client prima che il codice veda anche una sola riga. Per una query che restituisce dieci milioni di righe, ciò può significare centinaia di megabyte di memoria PHP. mysqli_use_result() evita questo costo: l'utilizzo della memoria rimane grossomodo costante indipendentemente da quante righe restituisce la query.

Sintassi

mysqli_use_result(mysqli $mysql): mysqli_result|false

Accetta l'oggetto connessione (o link) restituito da mysqli_connect() e restituisce un oggetto mysqli_result in caso di successo, o false in caso di errore. In stile orientato agli oggetti il metodo equivalente è $mysqli->use_result().

Bufferizzato vs. non bufferizzato: perché la distinzione è importante

Bufferizzato (store_result)Non bufferizzato (use_result)
Memoria lato PHPContiene l'intero set di risultatiCirca una riga alla volta
mysqli_num_rows()Disponibile immediatamenteSolo dopo aver recuperato tutte le righe
mysqli_data_seek()SupportatoNon supportato
La connessione durante la letturaLibera per nuove queryBloccata fino al completamento
Ideale perSet di risultati piccoli/mediSet di risultati molto grandi

Il compromesso principale: la modalità non bufferizzata è leggera sulla memoria ma occupa la connessione. Non è possibile eseguire un'altra query sulla stessa connessione fino a quando non si sono recuperate tutte le righe (o liberato il risultato). La modalità bufferizzata è l'opposto — più pesante sulla memoria, ma la connessione è libera nel momento in cui la query restituisce il risultato.

Come usare mysqli_use_result()

1. Connettersi al server MySQL

Prima aprite una connessione con mysqli_connect():

<?php

$host     = 'localhost';
$user     = 'username';
$password = 'password';
$database = 'mydatabase';

$connection = mysqli_connect($host, $user, $password, $database);

if (!$connection) {
    die('Connection failed: ' . mysqli_connect_error());
}

2. Eseguire la query, quindi avviare il recupero non bufferizzato

Per la modalità non bufferizzata è necessario eseguire la query senza chiedere a mysqli di memorizzare il risultato. Utilizzate il flag MYSQLI_USE_RESULT con mysqli_query() (oppure chiamate mysqli_real_query()), quindi chiamate mysqli_use_result():

$sql = "SELECT id, name FROM users";

// MYSQLI_USE_RESULT tells mysqli NOT to buffer the rows.
mysqli_real_query($connection, $sql);

$result = mysqli_use_result($connection);

if ($result) {
    while ($row = mysqli_fetch_assoc($result)) {
        // Process one row at a time — only this row lives in PHP memory.
        print_r($row);
    }
    mysqli_free_result($result);
}

Ogni chiamata a mysqli_fetch_assoc() recupera la riga successiva direttamente dalla rete. È possibile utilizzare allo stesso modo anche mysqli_fetch_row(), mysqli_fetch_array() o mysqli_fetch_all().

3. Liberare sempre il risultato

Chiamare mysqli_free_result() è più importante qui che in modalità bufferizzata: fino a quando il risultato non viene liberato (o letto completamente), la connessione rimane bloccata e inutilizzabile per qualsiasi altra query.

Regole e insidie

  • Leggere ogni riga prima della query successiva. Mentre un risultato non bufferizzato è aperto, la connessione è occupata. Tentare di eseguire un'altra query prima di completare il ciclo genera un errore "Commands out of sync". Completare il ciclo o chiamare prima mysqli_free_result().
  • Nessun conteggio delle righe in anticipo. mysqli_num_rows() restituisce il numero corretto solo dopo aver recuperato tutte le righe, perché il server non ha ancora comunicato al client quante ce ne sono.
  • Nessun accesso casuale. mysqli_data_seek() non funziona sui risultati non bufferizzati — è possibile avanzare solo in avanti.
  • Un risultato per connessione. È possibile mantenere aperto un solo risultato non bufferizzato su una connessione alla volta.

Quando usarlo?

Ricorrere a mysqli_use_result() quando una query restituisce molti più dati di quanti si vogliano tenere in memoria — esportazione di una tabella grande in CSV, streaming di un report o alimentazione di un risultato lungo riga per riga in un altro processo. In questi casi l'utilizzo costante della memoria rappresenta un vantaggio concreto.

Per le query ordinarie che restituiscono poche, o anche alcune migliaia, di righe, preferite la modalità bufferizzata predefinita tramite mysqli_query(). La comodità di mysqli_num_rows(), la ricerca casuale e una connessione libera quasi sempre supera il modesto risparmio di memoria.

Conclusione

mysqli_use_result() avvia un set di risultati MySQL non bufferizzato, recuperando le righe una alla volta in modo che l'utilizzo della memoria rimanga basso anche per set di risultati di grandi dimensioni. Il costo è che la connessione è bloccata fino al termine della lettura, si perdono mysqli_num_rows() e mysqli_data_seek(), e il risultato deve essere liberato tempestivamente. Usatela per dataset genuinamente grandi; preferite la modalità bufferizzata predefinita per le query ordinarie.

Pratica

Pratica
Quali sono i modi per usare un risultato da MySQL in PHP?
Quali sono i modi per usare un risultato da MySQL in PHP?
Was this page helpful?