Operaciones con registros¶
Insertando registros¶
A la hora de insertar registros en una base de datos, debemos tener en cuenta que en la tabla puede haber valores autoincrementales. Para salvaguardar ésto, lo que debemos hacer es dejar ese campo autoincrementado vacío, pero a la hora de hacer la conexión, debemos recuperarlo con el método lastInsertId()
.
<?php
$nombre = $_GET["nombre"] ?? "SUCURSAL X";
$telefono = $_GET["telefono"] ?? "636123456";
$sql="INSERT INTO tienda(nombre, tlf) VALUES (:nombre, :telefono)";
$sentencia = $conexion -> prepare($sql);
$sentencia -> bindParam(":nombre", $nombre);
$sentencia -> bindParam(":telefono", $telefono);
$isOk = $sentencia -> execute();
$idGenerado = $conexion -> lastInsertId();
echo $idGenerado;
Consultando registros¶
A la hora de recuperar los resultados de una consulta, bastará con invocar al método PDOStatement::fetch
para obtener las filas generadas por la consulta.
Pero debemos elegir el tipo de dato que queremos recibir entre los 3 que hay disponibles:
PDO::FETCH_ASSOC:
array indexado cuyos keys son el nombre de las columnas.PDO::FETCH_NUM:
array indexado cuyos keys son números.PDO::FETCH_BOTH:
valor por defecto. Devuelve un array indexado cuyos keys son tanto el nombre de las columnas como números.

A continuación vamos a recuperar y listar todas las tiendas de nuestra base de datos:
<?php
include "config/database.inc.php";
$conexion = null;
try {
$conexion = new PDO(DSN, USUARIO, PASSWORD);
$conexion -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "select * from tienda";
$sentencia = $conexion -> prepare($sql);
$sentencia -> setFetchMode(PDO::FETCH_ASSOC);
$sentencia -> execute();
while($fila = $sentencia -> fetch()){
echo "Código:" . $fila["cod"] . "<br />";
echo "Nombre:" . $fila["nombre"] . "<br />";
echo "Teléfono:" . $fila["tlf"] . "<br />";
}
} catch(PDOException $e) {
echo $e -> getMessage();
}
$conexion = null;
Si no queremos recuperar fila a fila, podemos obtener todos los datos mediante fetchAll
, recuperando datos con una matriz como resultado de nuestra consulta:
<?php
$sql="SELECT * FROM tienda";
$sentencia = $conexion -> prepare($sql);
$sentencia -> setFetchMode(PDO::FETCH_ASSOC);
$sentencia -> execute();
$tiendas = $sentencia -> fetchAll();
foreach($tiendasas$tienda) {
echo "Código:" . $tienda["cod"] . "<br />";
echo "Nombre:" . $tienda["nombre"] . "<br />";
}
PDO::FETCH_OBJ
, debemos crear un objeto con propiedades públicas con el mismo nombre que las columnas de la tabla que vayamos a consultar.
<?php
$sql="SELECT * FROM tienda";
$sentencia = $conexion -> prepare($sql);
$sentencia -> setFetchMode(PDO::FETCH_OBJ);
$sentencia -> execute();
while($t = $sentencia -> fetch()) {
echo "Código:" . $t -> cod . "<br />";
echo "Nombre:" . $t -> nombre . "<br />";
echo "Teléfono:" . $t -> tlf . "<br />";
}
Consultas con modelos¶
Llevamos tiempo creando clases en PHP y las consultas también admiten este tipo de datos mediante el uso de PDO::FETCH_CLASS
Si usamos este método, debemos tener en cuenta que los nombres de los atributos privados deben coincidir con los nombres de las columnas de la tabla que vayamos a manejar.
A considerar
Así pues, si por lo que sea cambiamos la estructura de la tabla debemos cambiar nuestra clase para que todo siga funcionando.
Si tenemos la siguiente clase Tienda
:
<?php
class Tienda {
private int $cod;
private string $nombre;
private ? string $tlf;
public function getCodigo() : int {
return $this -> cod;
}
public function getNombre() : string {
return $this -> nombre;
}
public function getTelefono() : ?string {
return $this -> tlf;
}
}
Podemos utilizarla mediante:
<?php
$sql = "SELECT * FROM tienda";
$sentencia = $conexion -> prepare($sql);
// Aquí 'Tienda' es el nombre de nuestra clase
$sentencia -> setFetchMode(PDO::FETCH_CLASS, "Tienda");
$sentencia -> execute();
while($t = $sentencia -> fetch()) {
echo "Codigo: " . $t -> getCodigo() . "<br />";
echo "Nombre: " . $t -> getNombre() . "<br />";
echo "Teléfono: " . $t -> getTelefono() . "<br />";
var_dump($t);
}
Pero ¿qué pasa si nuestras clases tienen constructor? pues que debemos indicarle, al método FECTH
, que rellene las propiedades después de llamar al constructor y para ello hacemos uso de PDO::FETCH_PROPS_LATE
.
<?php
$sql = "SELECT * FROM tienda";
$sentencia = $conexion -> prepare($sql);
$sentencia -> setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, Tienda::class);
$sentencia -> execute();
$tiendas = $sentencia -> fetchAll();
Consultas con LIKE¶
Para utilizar la claúsula LIKE
u otros comodines, debemos asociarlo al dato y nunca en la propia consulta, ya que si no estamos abriendo un agujero de seguridad para la inyección SQL.
<?php
$sql = "SELECT * FROM tienda where nombre like :nombre or tlf like :tlf";
$sentencia = $conexion -> prepare($sql);
$sentencia -> setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, Tienda::class);
$cadBuscar = "%" . $busqueda . "%";
$sentencia -> execute(["nombre" => $cadBuscar,"tlf" => $cadBuscar]);
$result = $sentencia -> fetchAll();
Tenéis una lista de ejemplos muy completa en la documentación oficial.
Actividad¶
-
PR 617. (RA6 / CE6b CE6c CE6d CE6e CE6f CE6g / IC2 / 5p) - Se te ha dado el visto bueno a tu propuesta de e-commerce. Ahora toca aumentar la complejidad y generar las siguientes acciones:
- Crear una pantalla de inicio de sesión en el frontal. En el momento del login se ha de actualizar la hora de conexión del cliente.
- Crear una pantalla de inicio de sesión en el backend. En el momento del login se ha de actualizar la hora de conexión del trabajador.
- Una vez que el cliente ha accedido, se ha de mostrar una pantalla con los pedidos y otra con los carritos que tiene pendientes de finalizar.
- Una vez que el trabajador ha accedido, se ha de mostrar un listado de los pedidos de la tienda ordenados por la fecha de creación.
Estructura de ficheros
Vas a tener que rehacer lo programado en PR 613 a
PDO::FETCH_ASSOC
.