- Stefanescu Mihai a postat in Paginare in PHP
- johhny a postat in Paginare in PHP
- Stefanescu Mihai a postat in Cum pot afisa eroarea cand utilizatorul a scris un username gresit sau o parola gresita?
- madalin a postat in Cum pot afisa eroarea cand utilizatorul a scris un username gresit sau o parola gresita?
- Stefanescu Mihai a postat in Featureuri site
Cum folosim noua extensie MySqli cu PHP
Dupa cum deja stiati, PHP a anuntat in 2011 ca extensia MySql va fi deprecated incepand cu versiunea PHP 5.5.0, urmand sa fie scoasa din functie mai apoi. In locul acestei extensii ni se ofera 2 alternative: MySqli (‘i’-ul din coada vine de la ‘improved’) si PDO (PHP Data Objects).
Cu totii stim ca modificarea unui proiect vechi din MySql in MySqli sau PDO poate fi destul de greu si chiar nu stiu ce vom face cu acestea, dar un lucru este sigur…nu trebuie sa mai scriem proiecte noi folosind vechea extensie.
In urma acestei modificari avem si anumite avantaje. De exemplu, PDO este orientat pe obiecte, iar MySqli vine cu suport atat pentru stilul procedural de programare cat si pentru stilul orientat pe obiecte. Ambele vin cu suport pentru prepared statements, tranzactii, si asa mai departe. Si o sa ma intrebati “Dar ce imi trebuie mie prepared statemenets?” .. pai, primul lucru care imi vine acum in minte este faptul ca aceste prepared statements va protejeaza aplicatia impotriva bine cunoscutului procedeu SQL Injection.
Si acum ma veti intreba “Pai si pana la urma eu ce trebuie sa folosesc? MySqli sau PDO?”. Raspunsul scurt ar fii acesta: “Pe care vrei”. Mie imi place sa folosesc MySqli, dar daca aveti nevoie de suport pentru mai multe tipuri de baze de date PDO este solutie ideala.
Cred ca am intins vorba destul si ar fii cazul sa va arat cateva chestii practice. Pentru exemplele de mai jos am sa folosesc extensia mysqli conectata la o baza de date mysql.
Instalarea
Cred ca in primul rand ar trebuii sa vorbim despre instalare…
Aceasta extensie este deja instalata (fie ca vorbim de linux sau windows) pentru ca vine deja instalata cu pachetul php5 mysql.Pentru a o instala pe un server Debian (sau ubuntu) folositi comanda:
apt-get install php5-mysql
Iar pe un Centos (sau Red Hat):
yum install php-mysql
Nu am sa scriu acum cum se poate instala pe toate tipurile de sistem de operare pentru gasiti aici toate instructiunile necesare.
Dupa instalare ar trebuii sa aveti ceva asemanator in phpinfo()
Conectarea
Sa incepem cu definirea parametrilor:
$DBServer = 'server name sau IP'; // de ex: 'localhost' sau '127.0.0.1' sau '192.168.1.100', depinde de serverul votstru $DBUser = 'DB_USER'; $DBPass = 'DB_PASSWORD'; $DBName = 'DB_NAME';
Conectarea folosind stilul orientat pe obiecte (recomdandat):
$conn = new mysqli($DBServer, $DBUser, $DBPass, $DBName); // Verificar conexiune if ($conn->connect_error) { trigger_error('Probleme de conectare: ' . $conn->connect_error, E_USER_ERROR); }
Conectarea in stilul procedural:
*Acest poate fi folosit de incepatorii in ale programarii orientate pe obiecte
$conn = mysqli_connect($DBServer, $DBUser, $DBPass, $DBName); // verificare conexiune if (mysqli_connect_errno()) { trigger_error('Probleme de conectare: ' . mysqli_connect_error(), E_USER_ERROR); }
Select
Pentru a folosi comanda de selectie folosim urmatoarea sintaxa:
$sql='SELECT col1, col2, col3 FROM nume_tabel WHERE conditie'; $rs=$conn->query($sql); if($rs === false) { trigger_error('Problema SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR); } else { $rows_returned = $rs->num_rows; }
Iterare inregistrari
Folosind numele coloanelor (recomandat):
$rs->data_seek(0); while($row = $rs->fetch_assoc()){ echo $row['col1'] . '<br/>'; }
Folosindu-ne de index:
$rs->data_seek(0); while($row = $rs->fetch_row()){ echo $row[0] . '<br/>'; }
Salvare valori in array
$rs=$conn->query($sql); if($rs === false) { trigger_error('Problema SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR); } else { $arr = $rs->fetch_all(MYSQLI_ASSOC); } foreach($arr as $row) { echo $row['co1']; }
*Folosind MYSQLI_ASSOC ne este returnat un array asociativ, folosind MYSQLI_NUM ne este returnat un array enumerat, iar MYSQLI_BOTH returneaza ambele tipuri de array
Salvare valori campuri in array
Urmatorul cod ne va returna un array cu primul rand din baza de date (atentie: folosind $rs->data_seek(n) putem returna orice rand dorim)
$rs=$conn->query($sql); if($rs === false) { trigger_error('Problema SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR); } else { $rs->data_seek(0); $arr = $rs->fetch_array(MYSQLI_ASSOC); }
Numar Randuri
$rows_returned = $rs->num_rows;
Eliberare memorie
$rs->free();
Insert
Ne este pusa la dispozitie urmatoarea sintaxa.
real_escape_string
este folosit pentru escaping de caractere speae (precum: NUL (ASCII 0), \n, \r, \, ', ", and Control-Z
) inainte de a adauga valorile primite de la utilizator in baza de date (pentru a preveni SQL Injection).
$v1="'" . $conn->real_escape_string('col1_value') . "'"; $sql="INSERT INTO tbl (col1_varchar, col2_number) VALUES ($v1,10)"; if($conn->query($sql) === false) { trigger_error('Problema SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR); } else { $last_inserted_id = $conn->insert_id; $affected_rows = $conn->affected_rows; }
Update
Sintaxa pentru update este urmatoarea:
$v1="'" . $conn->real_escape_string('col1_value') . "'"; $sql="UPDATE tbl SET col1_varchar=$v1, col2_number=1 WHERE id>10"; if($conn->query($sql) === false) { trigger_error('Problema SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR); } else { $affected_rows = $conn->affected_rows; }
Delete
Sintaxa:
$sql="DELETE FROM tbl WHERE id>10"; if($conn->query($sql) === false) { trigger_error('Problema SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR); } else { $affected_rows = $conn->affected_rows; }
Tranzactii
Avem urmatoarea sintaxa:
try { /* Setati autocommit la FALSE. Aceasta comanda incepe tranzactia */ $conn->autocommit(FALSE); $res = $conn->query($sql1); if($res === false) { throw new Exception('Problema SQL: ' . $sql . ' Error: ' . $conn->error); } $res = $conn->query($sql2); if($res === false) { throw new Exception('Problema SQL: ' . $sql . ' Error: ' . $conn->error); } $res = $conn->query($sql3); if($res === false) { throw new Exception('Problema SQL: ' . $sql . ' Error: ' . $conn->error); } $conn->commit(); echo 'Succes!'; } catch (Exception $e) { echo 'Probleme: ' . $e->getMessage(); $conn->rollback(); } /* schimbam valoarea lui autocommit */ $conn->autocommit(TRUE);
Conform http://www.php.net/manual/en/mysqli.commit.php#89976, folosind comanda$conn->commit() nu schimbam valoarea lui autocimmit() la TRUE. Ce inseamna asta? inseamna ca orice query scris dupa $conn->commit() va fi resetat la terminarea scriuptului atat timp cat autocommit nu este setat pe TRUE.
ATENTIE: Unele comenzi optiunea commit setata implicit, deci nu pot fi folosite in tranzactie. De exemplu: CREATE TABLE, TRUNCATE TABLE, s.a.m.d
Escaping Strings
Poate ati observat (in acest articol, sau in alta parte) ca inainte de a trimite informatii catre baza de date sunt verificate de caractere speciale (pentru a preveni atacurile SQL Injection)
$safe_string = $conn->real_escape_string($string);
De exemplu: bla"bla\bla
va deveni bla\"bla\\bla
.
Prepared Statements
Ce sunt aceste Prepared Statements si de ce sunt importante?
Prepared statements sunt folosite impreuna cu o declaratie sql ce poate prelua parametri (folosind diverse simboluri ce tin locul parametrului respectiv, de ex: ? in mysql sau $1 in PostgreSQL, etc).
Dupa ce o declaratie SQL a fost ‘preparata’, SGBD-ul o executa direct, nu mai trebuie sa o recompileze si sa pregateasca un plan de executare. Deci aici vom observa o oarecare optimizare (bineinteles ca aceasta optimizare se observa cel mai bine cand trebuie sa rulam un numar mare de query-uri similare).
Folosind acest procedeu nu mai trebuie sa verificam informatiile (ex: real_escape_string) pentru ca driverul face acest lucru (scade riscul de fi atacati prin SQL Injection).
Hai sa dam cateva exemple:
Select
$sql='SELECT nume, email FROM clienti WHERE id > ? AND numne = ?'; $id_mai_mare = 5; $nume = 'Ion'; /* Prepare statement */ $stmt = $conn->prepare($sql); if($stmt === false) { trigger_error('Problema SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR); } /* Bind parametrii. Tipuri: s = string, i = integer, d = double, b = blob */ $stmt->bind_param('is',$id_mai_mare,$nume); /* Execute statement */ $stmt->execute();
Iterare rezultate
$stmt->bind_result($nume, $email); while ($stmt->fetch()) { echo $nume. ', ' . $email . '<br>'; }
Salvare valori intr-un array
$rs=$stmt->get_result(); $arr = $rs->fetch_all(MYSQLI_ASSOC);
Inchidere statement
$stmt->close();
Insert
$sql='INSERT INTO clienti(nume, prenume) VALUES (?,?)'; $nume = 'Georgescu'; $prenume = 'Ion'; /* Prepare statement */ $stmt = $conn->prepare($sql); if($stmt === false) { trigger_error('Problema SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR); } $stmt->bind_param('ss',$nume,$prenume); /* Execute statement */ $stmt->execute(); echo $stmt->insert_id; echo $stmt->affected_rows; $stmt->close();
Update
$sql='UPDATE clienti SET nume = ?, prenume = ? WHERE id > ?'; $nume = 'Georgescu'; $prenume = 'Ion'; $id_conditie = 5; /* Prepare statement */ $stmt = $conn->prepare($sql); if($stmt === false) { trigger_error('Problema SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR); } $stmt->bind_param('ssi',$nume,$prenume,$id_conditie); /* Execute statement */ $stmt->execute(); echo $stmt->affected_rows; $stmt->close();
Delete
$sql='DELETE FROM clienti WHERE id > ?'; $id_conditie = 5; /* Prepare statement */ $stmt = $conn->prepare($sql); if($stmt === false) { trigger_error('Problema SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR); } $stmt->bind_param('i',$id_conditie); /* Execute statement */ $stmt->execute(); echo $stmt->affected_rows; $stmt->close();
Deconectare (* optional)
$conn->close();
Atat am avut de spus despre mysqli, sper ca ati inteles cat de cat si daca aveti intrebari nu ezitati sa mi le adresati prin rubrica de comentarii.
Comentarii
Inca nu au fost postate comentarii, fii primul care posteaza un comentariu!