mysqli_prepare în PHP

Baze de date (mysqli și PDO) PHP 5+ (execute cu tablou: PHP 8.1+, mysqli_execute_query: PHP 8.2+)

Pregătește o interogare SQL cu semne ? în loc de valori. Este metoda sigură împotriva SQL injection.

Sintaxă
mysqli_prepare(mysqli $mysql, string $query): mysqli_stmt|false

Ce face mysqli_prepare

O interogare pregătită (prepared statement) se trimite serverului în doi pași: întâi SQL-ul, cu ? în locul fiecărei valori, apoi valorile separat. Serverul nu confundă niciodată valorile cu comenzi SQL, deci un text precum ' OR 1=1 -- rămâne doar un text.

Pașii: mysqli_prepare creează interogarea; mysqli_stmt_bind_param($stmt, "si", $nume, $stoc) leagă variabilele (fiecare literă spune tipul: s text, i întreg, d număr cu zecimale, b date binare); mysqli_stmt_execute o rulează; mysqli_stmt_get_result dă rezultatul pentru SELECT.

Variante mai scurte: din PHP 8.1, mysqli_stmt_execute($stmt, [$a, $b]) primește valorile direct (toate trimise ca text), iar din PHP 8.2, mysqli_execute_query($conn, $sql, [$a, $b]) face totul într-un singur apel. La interogările pregătite, numerele vin în PHP ca int și float, nu ca text.

Exemplele de pe această pagină folosesc baza de date magazin, cu tabelul produse (coloanele id INT AUTO_INCREMENT, nume VARCHAR(100) NOT NULL, pret INT și stoc INT) și patru rânduri: Laptop (3200 lei, 5 buc.), Mouse (80 lei, 40 buc.), Monitor (900 lei, 0 buc.) și Tastatură (150 lei, 12 buc.). Comenzile SQL sunt explicate în secțiunea MySQL. Rezultatele au fost scrise pentru MySQL 8, pentru că exemplele au nevoie de un server de baze de date.

Parametri

Parametru Descriere
$mysql Conexiunea.
$query Comanda SQL, cu ? în locul valorilor. Nu pune ghilimele în jurul semnului ?.

Ce returnează

Un obiect mysqli_stmt. Din PHP 8.1, la eroare aruncă mysqli_sql_exception.

Exemple

Exemplul 1: SELECT cu valori de la utilizator

<?php
$conn = mysqli_connect("localhost", "ana", "parola_ta", "magazin");
mysqli_set_charset($conn, "utf8mb4");

$pretMaxim = 200;     // de exemplu din $_GET["pret_maxim"]
$cauta = "%a%";

$stmt = mysqli_prepare($conn, "SELECT id, nume, pret FROM produse WHERE pret <= ? AND nume LIKE ?");
mysqli_stmt_bind_param($stmt, "is", $pretMaxim, $cauta);
mysqli_stmt_execute($stmt);
$rezultat = mysqli_stmt_get_result($stmt);

while ($rand = mysqli_fetch_assoc($rezultat)) {
    var_dump($rand);
}

Rezultat (cu un server MySQL și tabelul produse de mai sus)

array(3) {
  ["id"]=>
  int(4)
  ["nume"]=>
  string(10) "Tastatură"
  ["pret"]=>
  int(150)
}

Exemplul 2: INSERT pregătit, rulat de mai multe ori

Interogarea se pregătește o singură dată. bind_param leagă variabilele, deci la fiecare execute se trimit valorile lor curente.

<?php
$conn = mysqli_connect("localhost", "ana", "parola_ta", "magazin");
mysqli_set_charset($conn, "utf8mb4");

$stmt = mysqli_prepare($conn, "INSERT INTO produse (nume, pret, stoc) VALUES (?, ?, ?)");
mysqli_stmt_bind_param($stmt, "sdi", $nume, $pret, $stoc);

foreach ([["Căști", 199.9, 8], ["Webcam", 249, 3]] as [$nume, $pret, $stoc]) {
    mysqli_stmt_execute($stmt);
    echo "Adăugat $nume cu id " . mysqli_insert_id($conn) . "\n";
}
mysqli_stmt_close($stmt);

Rezultat (cu un server MySQL și tabelul produse de mai sus)

Adăugat Căști cu id 5
Adăugat Webcam cu id 6

Exemplul 3: Varianta scurtă din PHP 8.2

<?php
$conn = mysqli_connect("localhost", "ana", "parola_ta", "magazin");
mysqli_set_charset($conn, "utf8mb4");

$rezultat = mysqli_execute_query($conn, "SELECT nume FROM produse WHERE id = ?", [2]);
echo mysqli_fetch_assoc($rezultat)["nume"];

Rezultat (cu un server MySQL și tabelul produse de mai sus)

Mouse

Greșeli frecvente

  • Pui ghilimele în jurul semnului întrebării: WHERE nume = '?'. Serverul caută atunci textul „?”. Scrie doar WHERE nume = ?.
  • Numărul de litere din "si" nu corespunde cu numărul de variabile sau de ?. Primești eroarea The number of elements in the type definition string must match the number of bind variables.
  • Încerci să pui un nume de tabel sau de coloană ca ?. Semnele ? pot înlocui doar valori; pentru nume de coloane folosește o listă de valori permise.

Comenzi înrudite

  • mysqli_query: Trimite o interogare SQL către baza de date. Pentru SELECT returnează un rezultat din care citești rândurile.
  • mysqli_fetch_assoc / mysqli_fetch_all / mysqli_fetch_array: Citește următorul rând dintr-un rezultat, ca tablou cu numele coloanelor drept chei.
  • mysqli_insert_id: Returnează id-ul generat automat (AUTO_INCREMENT) de ultimul INSERT.
  • mysqli_real_escape_string: Pune bară inversă în fața caracterelor speciale dintr-un text, ca să poată fi pus între ghilimele într-o interogare SQL.
  • PDO: PDO este interfața PHP comună pentru baze de date: același cod funcționează cu MySQL, PostgreSQL sau SQLite.