W3docs

PHP MySQLi

Scopri l'estensione PHP MySQLi: connettiti a MySQL, esegui query in modo sicuro con prepared statement per prevenire SQL injection e confronta MySQLi con PDO.

MySQLi ("MySQL Improved") è l'estensione PHP che si utilizza per connettersi a un database MySQL o MariaDB, eseguire query e leggere i risultati. Questo articolo spiega cos'è l'estensione, come connettersi, come eseguire query SELECT/INSERT/UPDATE in modo sicuro e quando scegliere MySQLi rispetto a PDO.

Cos'è l'estensione MySQLi?

L'estensione MySQLi è il successore delle vecchie funzioni mysql_* (ora rimosse). Aggiunge funzionalità che l'estensione originale non aveva: prepared statement, transazioni, istruzioni multiple e un corretto supporto per l'autenticazione MySQL 4.1+. È inclusa in PHP e abilitata per impostazione predefinita nella maggior parte delle installazioni.

MySQLi espone le stesse funzionalità attraverso due interfacce:

  • Orientata agli oggetti — si lavora con un oggetto mysqli e si chiamano metodi come $mysqli->query(). È lo stile usato dalla maggior parte del codice moderno e quello seguito in questo articolo.
  • Procedurale — si chiamano funzioni come mysqli_connect() e mysqli_query() passando la connessione come primo argomento.

Entrambe fanno esattamente la stessa cosa; scegli una e mantienila coerente. La forma orientata agli oggetti è più breve e si legge in modo più naturale.

Connessione a un database

Una connessione è rappresentata da un oggetto mysqli. Si crea passando host, nome utente, password e nome del database al costruttore, quindi si verifica che abbia avuto successo prima di procedere:

<?php
$mysqli = new mysqli("localhost", "username", "password", "my_database");

// Always check the connection before using it.
if ($mysqli->connect_error) {
    die("Failed to connect to MySQL: " . $mysqli->connect_error);
}

// Recommended: use UTF-8 so accented characters and emoji are stored correctly.
$mysqli->set_charset("utf8mb4");

echo "Connected successfully";
?>

La proprietà connect_error contiene un messaggio leggibile quando la connessione fallisce (o null in caso di successo). Chiamare set_charset() subito dopo la connessione evita in seguito sottili bug di codifica. Per approfondire l'apertura di una connessione, consulta PHP mysqli_connect() e il riferimento connect().

Esecuzione di una query SELECT

Una volta connessi, query() esegue SQL e restituisce un oggetto risultato su cui è possibile iterare. fetch_assoc() restituisce una riga alla volta come array associativo, oppure null quando non ci sono più righe:

<?php
$result = $mysqli->query("SELECT name, email FROM users");

if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
    }
} else {
    echo "No users found.";
}

$result->free();   // release the result set
$mysqli->close();  // close the connection when you are done
?>

num_rows indica quante righe sono state restituite, così puoi mostrare un messaggio appropriato quando una query non restituisce risultati. Consulta PHP MySQL Select Data per ulteriori pattern di query.

Prepared statement (il modo sicuro di usare l'input)

Non inserire mai l'input dell'utente direttamente in una stringa di query — è così che avviene la SQL injection. Un prepared statement invia SQL e dati separatamente, in modo che il database tratti l'input strettamente come un valore e mai come SQL eseguibile.

Si scrivono segnaposto ?, si esegue prepare() dell'istruzione, quindi bind_param() con i valori reali:

<?php
$age = 18;

$stmt = $mysqli->prepare("SELECT name, email FROM users WHERE age > ?");
$stmt->bind_param("i", $age);   // "i" = integer (s = string, d = double, b = blob)
$stmt->execute();

$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
    echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}

$stmt->close();
?>

Il primo argomento di bind_param() è una stringa di tipo: un carattere per segnaposto — i (integer), s (string), d (double/float) o b (blob). Gli argomenti rimanenti sono i valori, nell'ordine.

Nota: get_result() richiede il driver mysqlnd, che è quello predefinito nel PHP moderno. Se la tua build non lo include, usa bind_result() per associare le colonne a variabili.

Per una guida dedicata, consulta PHP MySQL Prepared Statements.

Inserimento e aggiornamento dei dati

Lo stesso pattern con prepared statement funziona per le scritture. Dopo un INSERT, l'id auto-increment della nuova riga è disponibile in $mysqli->insert_id; dopo un INSERT/UPDATE/DELETE, $mysqli->affected_rows indica quante righe sono state modificate:

<?php
$name  = "Ada Lovelace";
$email = "[email protected]";

$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email);   // two strings
$stmt->execute();

echo "Inserted user #" . $mysqli->insert_id;
$stmt->close();
?>

Consulta PHP MySQL Insert Data e PHP MySQL Update Data per il quadro completo del CRUD.

Gestione degli errori

Se una query fallisce, query() restituisce false e i dettagli sono sull'oggetto connessione. Leggere $mysqli->error dopo una chiamata fallita indica cosa è andato storto:

<?php
if (!$mysqli->query("SELECT * FROM no_such_table")) {
    echo "Query failed (" . $mysqli->errno . "): " . $mysqli->error;
}
?>

In fase di sviluppo puoi far lanciare eccezioni automaticamente a MySQLi con mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT), che è il comportamento predefinito da PHP 8.1. Letture correlate: PHP connect_error e PHP connect_errno.

MySQLi vs. PDO — quale scegliere?

Entrambi sono modi sicuri e moderni di comunicare con un database. In breve:

  • MySQLi funziona solo con MySQL/MariaDB. Espone alcune funzionalità specifiche di MySQL (come le query asincrone) che PDO non supporta.
  • PDO (PHP Data Objects) supporta una dozzina di database attraverso un'unica API, quindi passare da MySQL a PostgreSQL significa cambiare una stringa di connessione, non le query. Supporta anche segnaposto con nome (:name) che sono più leggibili.

Se sai che userai solo MySQL, MySQLi va benissimo. Se la portabilità è importante, preferisci PDO. In ogni caso, usa sempre i prepared statement.

  • MySQLi è l'estensione standard per lavorare con MySQL/MariaDB in PHP, disponibile sia in stile orientato agli oggetti che procedurale.
  • Crea una connessione con new mysqli(...), verifica connect_error e imposta il charset.
  • Usa query() + fetch_assoc() per leggere dati e iterare sui risultati.
  • Usa i prepared statement (prepare()bind_param()execute()) per qualsiasi cosa che coinvolga input utente per proteggerti dalla SQL injection.
  • Controlla $mysqli->error / $mysqli->errno quando una query fallisce, e preferisci PDO quando hai bisogno di portabilità del database.

Pratica

Pratica
Quali sono le caratteristiche importanti di PHP MySQLi?
Quali sono le caratteristiche importanti di PHP MySQLi?
Was this page helpful?