W3docs

multi_query

Guida alla funzione mysqli_multi_query() in PHP per eseguire più query in una sola chiamata, con sintassi, parametri ed esempi pratici.

In questo articolo ci concentreremo sulla funzione mysqli_multi_query() in PHP, che esegue una o più istruzioni SQL in una singola chiamata. Ne analizzeremo la sintassi, i parametri e il valore di ritorno, vedremo un esempio eseguibile e spiegheremo come leggere in modo sicuro più set di risultati.

Cos'è mysqli_multi_query()?

mysqli_multi_query() è una funzione built-in di PHP che invia una o più istruzioni SQL, separate da punto e virgola, al server MySQL in un unico scambio di rete. Fa parte dell'estensione MySQLi, l'interfaccia migliorata di PHP per comunicare con MySQL.

È utile quando si dispone di un gruppo di istruzioni da eseguire tutte insieme — per esempio, per popolare più tabelle all'avvio o per eseguire una stored procedure che restituisce più set di risultati. Poiché ogni istruzione viene comunque eseguita in modo indipendente sul server, mysqli_multi_query() non sostituisce una transazione quando si ha bisogno di un comportamento tutto-o-niente (vedi Quando non usarla).

Sintassi

La funzione funziona sia nello stile procedurale che in quello orientato agli oggetti:

// Procedural style
mysqli_multi_query(mysqli $mysqli, string $query): bool

// Object-oriented style
$mysqli->multi_query(string $query): bool

Parametri

ParametroDescrizione
$mysqliUna connessione valida restituita da mysqli_connect().
$queryUna stringa con una o più istruzioni SQL separate da un punto e virgola (;).

Valore di ritorno

Restituisce false se la prima istruzione fallisce, altrimenti true. Un valore di ritorno true significa solo che la prima query è stata accettata — è necessario iterare sui risultati per rilevare errori nelle istruzioni successive.

Come usare mysqli_multi_query()

Chiama la funzione su una connessione MySQLi valida con una stringa di istruzioni separate da punto e virgola, poi scorri i set di risultati. Ecco un esempio completo:

<?php
$mysqli = mysqli_connect("localhost", "username", "password", "database");

if (!$mysqli) {
    die("Connection failed: " . mysqli_connect_error());
}

$query = "INSERT INTO table1 VALUES ('value1', 'value2', 'value3');";
$query .= "UPDATE table2 SET column1 = 'newvalue' WHERE id = 1;";

if (mysqli_multi_query($mysqli, $query)) {
    do {
        if ($result = mysqli_store_result($mysqli)) {
            while ($row = mysqli_fetch_row($result)) {
                print_r($row);
            }
            mysqli_free_result($result);
        }
    } while (mysqli_next_result($mysqli));
} else {
    echo "Error: " . mysqli_error($mysqli);
}

mysqli_close($mysqli);
?>

Ecco cosa fa ciascuna parte:

  1. mysqli_connect() apre una connessione al database MySQL; se fallisce, si interrompe immediatamente.
  2. Costruiamo una singola stringa contenente due istruzioni separate da punto e virgola.
  3. mysqli_multi_query() invia entrambe le istruzioni al server in una sola chiamata.
  4. Il ciclo do...while legge ogni set di risultati a turno. mysqli_store_result() memorizza nel buffer il risultato corrente, mysqli_fetch_row() legge le sue righe e mysqli_next_result() avanza al successivo.
  5. mysqli_close() rilascia la connessione.

Gestione di più set di risultati

Questa è la parte che gli sviluppatori sbagliano più spesso. Dopo un mysqli_multi_query() andato a buon fine, si deve consumare ogni set di risultati — anche quelli vuoti prodotti da INSERT o UPDATE — prima di poter eseguire un'altra query sulla stessa connessione. Saltare questo passaggio provoca un errore "Commands out of sync".

Il pattern sicuro è:

<?php
do {
    // Buffer the current result set, if any.
    if ($result = mysqli_store_result($mysqli)) {
        while ($row = mysqli_fetch_row($result)) {
            print_r($row);
        }
        mysqli_free_result($result);
    }
    // mysqli_more_results() avoids a spurious warning on the last loop.
} while (mysqli_more_results($mysqli) && mysqli_next_result($mysqli));
?>

mysqli_next_result() restituisce false quando non ci sono altri risultati, uscendo così dal ciclo. Verificare prima mysqli_more_results() evita l'emissione di un avviso dopo l'ultima istruzione.

Quando non usarla

mysqli_multi_query() è potente ma facile da usare male:

  • Non passare mai direttamente input dell'utente nella stringa della query. Concatenare dati non attendibili qui rappresenta un classico vettore di SQL injection, e questa funzione non supporta parametri vincolati. Per qualsiasi cosa che coinvolga input dell'utente, eseguire ciascuna istruzione separatamente con istruzioni preparate — vedi mysqli_prepare().
  • Non è atomica. Se la seconda istruzione fallisce, la prima è già stata eseguita. Quando più istruzioni devono avere successo o fallire insieme, racchiudi le singole query in una transazione con mysqli_begin_transaction(), mysqli_commit() e mysqli_rollback().
  • Controlla sempre il valore di ritorno e itera i risultati per intercettare errori nelle istruzioni successive alla prima.

Conclusione

La funzione mysqli_multi_query() consente di eseguire più istruzioni SQL in una singola chiamata, il che è comodo per le operazioni batch. La chiave per usarla correttamente è consumare ogni set di risultati con mysqli_next_result() per evitare errori "Commands out of sync", e ricorrere alle istruzioni preparate e alle transazioni ogni volta che sono coinvolti input dell'utente o è richiesta l'atomicità.

Esercitazione

Pratica
Qual è lo scopo principale della funzione 'multi_query' in PHP?
Qual è lo scopo principale della funzione 'multi_query' in PHP?
Was this page helpful?