Altres: Bases de Dades¶
Tractarem com accedir a informació a bases de dades i realitzar funcions bàsiques o necessàries sobre informació en un projecte.
Com a base podeu accedir a la informació oficial o bé w3schools
Normalment usarem una BdD MySQL, tot i que usant PDO ens podem conectar a qualsevol BdD que hi tinguem drivers de conexió.
El llenguatge PHP disposa de dues opcions:
- mysqli: que pot ser procedimental o objectes i es connecta a una BdD MySQL
- PDO: que està basada en objectes i ens permet connectar a qualsevol BdD
El SGBDR ens permet treballar com a interfície per a la nostra aplicació PHP i ens permet accedir a la informació guardada a la BdD
Tenim dos conceptes:
- QUÈ: serà la manera que direm com accedim a la informació. Usant SQL.
- COM: é sel SGDDR que realitzarà internament l'accés a la informació.
El SQL es divideix en tres blocs:
- DML: Llenguatge de Manipulació de Dades. Per exemple: SELECT, INSERT, UPDATE, DELETE, ...
- DDL: Llenguatge de Definició de Dades. Per exemple: CREATE, ALTER, DROP, ...
- DCL: Llenguatge de Control de Dades. Per exemple: GRANT, REVOKE, ...
Lògica d'accés a la informació d'una BdD¶
De manera bàsica farem:
- Conexió a una BdD, indicant servidor, usuari, contrasenya i BdD
- Preparar sentència SQL
- Executar sentència SQL
- Si hem fet SQL SELECT
- Recollim informació
- Acció amb la informació
- Tancar conexió
Si usem PDO, tindrem 3 classes definides:
- PDO: Conexió entre PHP i la BdD
- PDOException: Control de les excepcions ocorregudes
- PDOStatement: Consulta preparada, executem i resultat obtingut.
Conexió a una BdD¶
Usant MySQLi
<?php
$servername = "localhost";
$username = "username";
$password = "password";
// Create connection
$conn = mysqli_connect($servername, $username, $password);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "Connected successfully";
?>
Usant PDO
<?php
$servername = "localhost";
$username = "username";
$password = "password";
try {
$conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
?>
Executar una sentència simple¶
Podem executar i obtenir els resultats d'una sentència SQL simple de manera ràpida i fàcil amb PDO->query()
$SQL = "SELECT * FROM CLients ORDER BY Nom";
$rst = $conn->query($SQL);
Ens retorna un array de resultats.
* NOTA
L'execució d'una sentència SQL amb query no controla la injectació d'atacs SQL
Si que ho podrem controlar millor amb `prepare()` i `execute()`.
També podem usar PDO->exec()
, executa una sentència i ens retorna el número de resgistres.
$SQL = "DELETE FROM CLients WHERE id=3";
$count = $conn->exec($SQL);
echo "$count registres eliminats";
Ens anirà molt bé per executar consultes SQL que no retornin específicament resultats d'una SELECT
, per exemple sentències DDL, com CREATE TABLE
.
Preparar una sentència SQL¶
La classe PDOStatement és la que usarem per tractar les sentències SQL.
Una instància de la classe PDOStatement es crea quan es crida a PDO->prepare()
.
Associem els paràmetres amb bindparam()
i tot seguit execute()
.
Amb això obtenim millora del rendiment i seguretat en la consulta. Per exemple evitar injectació de SQL per part de robots en accés a formularis web.
Preparar -> Associar valors -> Executar
un exemple:
$SQL = "SELECT * FROM Alumnes WHERE DNI=:DNI";
$rst = $conn->prepare($SQL);
$DNI = "40000000-A";
$rst->bindparam(":DNI",$DNI);
$rst->execute();
bindparam()
tant ens permet utilitzar ?
com :variable
$SQL = "INSERT INTO Alumnes (DNI,Nom) VALUES (?,?)";
$rst = $conn->prepare($SQL);
$DNI = "40000000-A";
$Nom = "Laia Bosch";
$rst->bindparam(1,$DNI);
$rst->bindparam(2,$Nom);
$rst->execute();
També ens permet passar un array de valors:
$SQL = "INSERT INTO Alumnes (DNI,Nom) VALUES (:DNI,:Nom)";
$rst = $conn->prepare($SQL);
$DNI = "40000001-B";
$Nom = "Maria Soler";
$rst->execute(array(':DNI'=>$DNI,':Nom'=>$Nom));
Podem usar tant:
- bindParam(): la variable s'enllaça com una referència i només s'avalua quane s crida execute().
- bindValue(): la variable s'enllaça al valor fins que s'eceuta la sentència amb execute().
Consultar dades¶
Una vegada s'ha executat la consulta s'obté el resultat de la mateixa.
Per fer-ho usem fetch
. Això ens retorna un registre amb les dades obtingudes de la consulta SQL.
Cal indicar com obtenim l'array de dades:
- PDO::FETCH_ASSOC: torna un array indexat amb les claus dels noms de les columnes de la taula de la bdd.
- PDO::FETCH_NUM: torna un array indexat on la clau són números de posició.
Tenim més formes d'obtenir els resultats
llavors només cal recorrer l'array obtingut
$SQL = "SELECT * FROM CLients ORDER BY Nom";
$rst = $conn->query($SQL);
while ($row = $rst->fetch())
echo $row["DNI"] . " - " . $row["Nom"];
Un exemple d'usar retorn d'un objecte
$SQL = "SELECT * FROM CLients ORDER BY Nom";
$rst = $conn->query($SQL);
while ($row = $rst->fetch(PDO::FETCH_OBJ))
echo $row->DNI . " - " . $row->Nom;
Si volem obtenir tots els registres usarem fetchAll()
. Ara obtindrem tots els registres i haurem de recorrer l'array obtingut
$SQL = "SELECT * FROM CLients ORDER BY Nom";
$rst = $conn->query($SQL);
$clients = $rst->fetchAll()
foreach($clients as $client)
echo $client["DNI"] . " - " . $client["Nom"];
Transaccions¶
Les transaccions ens permeten controlar l'execució de diverses sentències agrupades de SQL i que ens cal que cap d'elles ens retorni errada. Ens permetrà desfer-les totes en cas d'errada o confirma-les si totes han anat bé.
Una transacció s'inicia amb PDO::beginTransaction()
Validem totes les sentències SQL executades amb PDO::commit()
Desfem totes les sentències SQL executades amb PDO::rollback()
Per tant podem controlar la integritat de les dades segons s'haginpogut executar totes les sentències SQL correctment o no.
Usarem el try - catch
per controlar la transacció.
try
{
$conn->beginTransaction();
$conn->query($SQL1);
$conn->query($SQL2);
$conn->query($SQL3);
...
$conn->commit();
echo "Sentències SQL correctes";
}
catch (Exception $e)
{
$conn->rollback();
echo "Hi ha hagut alguna errada";
}