View on GitHub

apunts

Apunts DWES

Acces a Bases de dades

Accés a BBDD des de PHP

Establiment de la connexió

Video

Per exemple, si utilitzem el controlador per a Mysql, la cadena DSN rebrà els paràmetres següents (a continuació del prefix mysql:

$conn = new PDO ('mysql:host=mysql;port=3306;dbname=juegoRol', 'root', '1234');

Class PDOException

Totes les excepcions que genera PDO són del tipus PDOException que hereta de la classe Exception. Si hagueren errors de connexió, es llançarà una excepció PDOException. Si no capturem l’excepció, es finalitzarà el script i mostrarà informació de seguiment, que podria revelar detalls de la connexió a la base de dades, incloent el nom d’usuari i la contrasenya

Presentació i recuperació de dades

Video

<?php
$parametres_connexio = 'mysql:host=localhost;port=3306;dbname=test';
$usuari = 'root';
$passwd = '...';
try {
		$bd = new PDO($parametres_connexio,$usuari,$passwd);
		echo "Connexio realitzada correctament!!<br/>";
		$sql = "SELECT producte, unitats  FROM stock";
		$productes =  $bd->query($sql);
		echo $productes->rowCount()." elements<br/>";
		echo '<ul>';
		//dues maneres
		
		foreach ($productes->fetchAll as $producte){
			echo '<li>'.$producte['producte'].' '.$producte['unitats'].'</li>';
		}
		
		foreach ($productes->fetchAll(PDO::FETCH_OBJ) as $producte){
			echo '<li>'.$producte->producte.' '.$producte->unitats.'</li>';
		}
		echo '</ul>';
	} catch (PDOException $e) {
    echo 'Error con la base de datos: ' . $e->getMessage();
	} 

Inserció, esborrat i modificat

S’utilitza el mètode PDO::exec, que executa una sentència SQL i retorna el nombre de registres afectats

	$registres = $pdo->exec('DELETE FROM stock WHERE unitats=0');  
	echo "\<p>S'han esborrat $registres registres.\</p>";

Aquesta sentència és vulnerable a injeccions SQL. En el seu lloc es recomana utilitzar consultes preparades

<?php
// datos conexión
$cadena_conexion = 'mysql:host=localhost;port=3306;dbname=test';
$usuario = 'root';
$clave = '';
try {
	// conectar
    $bd = new PDO($cadena_conexion, $usuario, $clave);	
	echo "Conexión realizada con éxito<br>";	
	// insertar nuevo usario
	$ins = "insert into usuarios(nombre, clave, rol) values('Alberto', '33333', '1');";
	$resul = $bd->exec($ins);	
	//comprobar errores
	if($resul) {
		echo "insert correcto <br>";
		echo "Filas insertadas: " . $resul . "<br>";
	}else print_r( $bd->errorinfo());	
	// para los autoincrementos
	echo "Código de la fila insertada" . $bd->lastInsertId() . "<br>"; 
	
	// actualizar
	$upd = "update usuarios set rol =  0 where rol = 1";
	$resul = $bd->exec($upd);	
	//comprobar errores
	if($resul){
		echo "update correcto <br>";
		echo "Filas actualizadas: " . $resul->rowCount() . "<br>";
	}else print_r( $bd->errorinfo());	
	
	// borrar
	$del = "delete from usuarios where nombre = 'Luisa'";
	$resul = $bd->exec($del);	
	//comprobar errores
	if($resul){
		echo "delete correcto <br>";
		echo "Filas borradas: " . $resul->rowCount() . "<br>";
	}else print_r( $bd->errorinfo());
	
} catch (PDOException $e) {
	echo 'Error con la base de datos: ' . $e->getMessage();
} 

Consultes preparades

Ens aporten dos avantatges importants:

Utilitzem el mètode prepare de la classe PDO que retorna un objecte de la classe PDOStatement. A més, els paràmetres es poden marcar utilitzant signes d’interrogació o amb nom, utilitzant :.

 $pdoSt = $pdo->prepare('INSERT INTO família (cod,nom)  VALUES (?, ?)');
 $pdoSt = $pdo->prepare('INSERT INTO família (cod,nom)  VALUES (:cod,:nom)');

Abans d’executar la consulta, cal assignar un valor als paràmetres.Utilitzem el mètode bindParam de la classe PDOStatement. Si hem utilitzat signe d’interrogació posarem l’índex del paràmetre començant per 1. Si usem paràmetres amb nom, indiquem el nom en la cridada a bindParam.

$cod_producte = " TABLET";  
$nom_producte = " Tablet PC"; 
$pdoSt->bindParam(1,$cod_producte); 
$pdoSt->bindParam(2,$nom_producte);
$pdoSt->bindParam(":cod",$cod_producte); 
$pdoSt->bindParam(":nom",$nom_producte);

Una vegada preparada la consulta i enllaçats els paràmetres amb els seus valors, s’executa la consulta utilitzant el mètode execute de la classe PDOStatement. També, és possible assignar els valors dels paràmetres en el moment d’executar la consulta, utilitzant un array (associatiu o amb claus numèriques depenent de la forma en què hages indicat els paràmetres) en la cridada a execute

<?php
$cadena_conexion = 'mysql:host=localhost;port=3306;dbname=test';
$usuario = 'root';
$clave = '';
try {
	   $bd = new PDO($cadena_conexion, $usuario, $clave);
		echo "Conexión realizada con éxito<br>";		
		$sql = 'SELECT nombre, clave, rol FROM usuarios';
		$usuarios = $bd->query($sql);
		echo "Número de usuarios: " . $usuarios->rowCount() . "<br>";
		foreach ($usuarios->fetchAll(PDO::FETCH_OBJ) as $usu) {
			print "Nombre : " . $usu->nombre;
			print "Clave : " . $usu->clave . "<br>";
		}
		
		/* consulta preparada, parametros por orden */	
		$preparada = $bd->prepare("select nombre from usuarios where rol = ?");	
		$preparada->execute( array(0));
		echo "Usuarios con rol 0: " .  $preparada->rowCount() . "<br>";
		foreach ($preparada->fetchAll(PDO::FETCH_OBJ) as $usu) {
			print "Nombre : " . $usu->nombre . "<br>";
		}
		
		/* consulta preparada, parametros por nombre */	
		$preparada_nombre = $bd->prepare("select nombre from usuarios where rol = :rol");
		$preparada_nombre->execute( array(':rol' => 0));
		echo "Usuarios con rol 0: " .  $preparada->rowCount() . "<br>";
		foreach ($preparada_nombre->fetchAll(PDO::FETCH_OBJ)  as $usu) {
			print "Nombre : " . $usu->nombre . "<br>";
		}	
	} catch (PDOException $e) {
		echo 'Error con la base de datos: ' . $e->getMessage();
	}

QueryBuilder

Un Query Builder conté una sèrie de funcions llestes per a realitzar les operacions més comunes amb una base de dades, però sense usar el llenguatge SQL directament. Podem instal·lar alguno com Eloquent o el de Doctrine. En esta sèrie de videos es mostra com anar implementant un:

Mètode find : Video

Utilitzant el mètode find dins d’una classe per a implementar un modelo de dades: Video

Mètode insert: Video

Transaccions

Video

Una transacció consistix en un conjunt d’operacions que han de realitzar-se de forma atòmica. Es a dir, o es realitzen totes o cap.

Per defecte PDO treballa en manera autocommit, així esconfirma de forma automàtica cada sentència que executa el servidor.

Per a treballar amb transaccions, PDO incorpora tres mètodes:

Una vegada executat un commit o un rollback, es tornarà a la manera de confirmació automàtica

	<?php
	$cadena_conexion = 'mysql:host=localhost;port=3306;dbname=test';
	$usuario = 'homestead';
	$clave = 'secret';
	try {
	    $bd = new PDO($cadena_conexion, $usuario, $clave);
		echo "Conexión realizada con éxito<br>";
		// comenzar la transacción
		$bd->beginTransaction();	
		$ins = "insert into usuarios(nombre, clave, rol) values('Fernando', '33333', '1')";
		$resul = $bd->exec($ins);	
		// se repite la consulta
		// falla porque el nombre es unique
		$resul = $bd->exec($ins);	
		if(!$resul){
			echo "Error: " . print_r($bd->errorinfo());
			// deshace el primer cambio
			$bd->rollback();
			echo "<br>Transacción anulada<br>";
		}else{
			// si hubiera ido bien...
			$bd->commit();
		}	
	} catch (PDOException $e) {
	    echo 'Error al conectar: ' . $e->getMessage();
	}