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";
}