1. Universidad Politécnica Territorial Andrés Eloy Blanco
Programa Nacional de Formación en Informática
Ing. Lissette Torrealba
1. Conceptos básicos: BD, Tablas, Registros, Sistema Gestor de BD, SQL
Unidad X y XI
Herramientas de Base de Datos e Integración de Herramientas de Seguridad
Objetivo de la Unidad:
Definición
Una de las aplicaciones más frecuentes de PHP es generar un interface web para acceder y gestionar la
información almacenada en una base de datos. Usando PHP podemos mostrar en una página web
información extraída de la base de datos, o enviar sentencias al gestor de la base de datos para que
elimine o actualice algunos registros.
PHP soporta más de 15 sistemas gestores de bases de datos: SQLite, Oracle, SQL Server,
PostgreSQL, IBM DB2, MySQL, etc. Hasta la versión 5 de PHP, el acceso a las bases de datos se
hacía principalmente utilizando extensiones específicas para cada sistema gestor de base de datos
(extensiones nativas). Es decir, que si queríamos acceder a una base de datos de PostgreSQL,
deberíamos instalar y utilizar la extensión de ese gestor en concreto. Las funciones y objetos a
utilizar eran distintos para cada extensión.
A partir de la versión 5 de PHP se introdujo en el lenguaje una extensión para acceder de una forma
común a distintos sistemas gestores: PDO. La gran ventaja de PDO está clara: podemos seguir
utilizando una misma sintaxis aunque cambiemos el motor de nuestra base de datos. Por el
contrario, en algunas ocasiones preferiremos seguir usando extensiones nativas en nuestros
programas. Mientras PDO ofrece un conjunto común de funciones, las extensiones nativas
normalmente ofrecen más potencia (acceso a funciones específicas de cada gestor de base de
datos) y en algunos casos también mayor velocidad.
Introducción
El objetivo de la presente guía, es facilitar el estudio sobre las técnicas para la creación de diseños
de bases de datos, su montaje en un sistema gestor de bases de datos (sgbd) como lo es postgres;
para que a través de Crear, Leer, Actualizar y Borrar (crud) para finalmente, orientar la creación de
una aplicación que utilice Framework css para facilitar la construcción de interfaces de usuario, el
lenguaje de programación orientado a objetos PHP y el uso del patrón mvc que permite tener una
separación lógica y física de los componentes de la aplicación. El uso de estos elementos se
constituye en un patrón internacionalmente aceptado, faculta a su vez a los diseñadores y
desarrolladores de la aplicación y favorece a una excelente organización del trabajo.
Objetivo.
Diseñar bases de datos para la construcción de un crud con aplicaciones Web orientado a objeto a
través de la interfaz PDO utilizando el patrón mvc (modelo-vista-controlador).
Requerimientos.
Se debe contar con: Un (1) computador teniendo como mínimo el Sistema Operativo Libre ( Canaima/Ubuntu), Apache,
PHP, Editor de Texto.
Componentes.
2. Universidad Politécnica Territorial Andrés Eloy Blanco
Programa Nacional de Formación en Informática
Ing. Lissette Torrealba
La extensión PDO nos facilitará mucho la vida a la hora de trabajar con bases de datos, ya que nos
permite abstraernos del tipo de gestor de base de datos que estemos utilizando. Esto quiere decir
que sin el uso de PDO, si por ejemplo decides migrar tu aplicación de MySQL a PostgreSQL tendrías
que cambiar todos los métodos del conector de MySQL por los métodos de PostgreSQL. Con PDO
bastaría con que se cambie únicamente la creación del objeto PDO, donde se especifica el tipo de
base de datos a conectar, y el resto de la aplicación seguiría funcionando igual. Por lo que esta
abstracción del acceso de datos convierte a esta extensión en un elemento muy importante para la
portabilidad de la aplicación/web.
Que es PDO
PDO (PHP Data Objects) proporciona una capa abstracta de acceso a bases de datos:
independientemente de la base de datos que se esté utilizando, PDO permite usar las mismas
funciones para realizar consultas y obtener datos. Sin embargo, PDO no proporciona una
abstracción de las bases de datos, no reescribe las sentencias SQL y no emula características
ausentes en la base de datos. PDO se basa en las características de orientación a objetos de PHP
La interfaz de PDO proporciona tres clases:
PDO: se encarga de gestionar las conexiones entre PHP y un servidor de bases de datos.
Proporciona
métodos para gestionar las transacciones, obtener información sobre la conexión a la base de datos
y preparar y ejecutar sentencias.
PDOStatement: representa una sentencia preparada y el resultado asociado a una consulta.
Proporciona
métodos para asignar valores a una sentencia preparada, para obtener información sobre un
resultado (número de columnas, número de filas) y para recorrer un resultado.
PDOException: representa una excepción, un error generado por PDO. Proporciona métodos para
obtener información sobre el error producido.
Clase PDO
Las conexiones se establecen creando instancias de la clase PDO. El constructor de esta clase
acepta parámetros para especificar el origen de datos (conocido como DSN, Data Source Name) y,
opcionalmente, el nombre de usuario, la contraseña y opciones para el controlador. Los métodos
más importantes de esta clase son:
exec(sentencia): ejecuta una sentencia SQL que no devuelva un resultado (por ejemplo,
INSERT,UPDATE o DELETE) y devuelve el número de filas afectadas.
lastInsertId(): devuelve el ID autonumérico de la última fila insertada.
prepare(sentencia): crea y devuelve una sentencia preparada para su posterior ejecución.
query(sentencia): ejecuta una sentencia SQL y devuelve el resultado como un objeto de tipo
Clase PDOStatement.
La clase PDOStatement posee los siguientes métodos principales:
bindParam(parametro, variable): vincula una variable a un parámetro en una sentencia
preparada.
bindValue(parametro, valor): vincula un valor a un parámetro en una sentencia preparada.
columnCount(): devuelve el número de columnas de un resultado.
execute(): ejecuta una sentencia preparada.
fetch(estilo): devuelve la siguiente fila en un resultado. La forma de devolver la fila se controla
con el parámetro estilo que puede tomar los valores:
3. Universidad Politécnica Territorial Andrés Eloy Blanco
Programa Nacional de Formación en Informática
Ing. Lissette Torrealba
PDO::FETCH_ASSOC: devuelve un array indexado por los nombres de las columnas del
resultado.
PDO::FETCH_BOTH (predeterminado): devuelve un array indexado tanto por los nombres
de las columnas como por las posiciones de las columnas en el resultado comenzando por la
columna 0.
PDO::FETCH_NUM: devuelve un array indexado por las posiciones de las columnas en el
resultado comenzando por la columna 0.
PDO::FETCH_OBJ: devuelve un objeto anónimo con nombres de propiedades que se
corresponden a los nombres de las columnas del resultado.
fetchAll(estilo): devuelve un array que contiene todas las filas de un resultado. La forma de
devolver las filas se controla con el parámetro estilo que puede tomar los mismos valores que
el método fetch(estilo).
fetchObject(): devuelve la siguiente fila de un resultado en forma de objeto.
rowCount(): devuelve el número de filas afectadas por la última sentencia SQL.
Clase PDOException
Posee los siguientes métodos principales
getMessage(): devuelve el mensaje de la excepción.
Por defecto, la generación de excepciones está desactivada y no se producen excepciones (sin
embargo, cuando se produce un error en la conexión, siempre se produce una excepción). Para
activar la generación de excepciones se debe emplear el método setAttribute para modificar el
atributo de configuración de errores.
PDO::ATTR_ERRMODE con el valor PDO::ERRMODE_EXCEPTION:
PDO::ERRMODE_SILENT: el valor por defecto, no se generan excepciones (excepto para un error
de conexión).
PDO::ERRMODE_WARNING: los errores generan una advertencia de PHP y continúa la ejecución
(útil para depurar un código).
PDO::ERRMODE_EXCEPTION: se genera una excepción cuando se produce un error.
Veamos son Excepciones en PHP
Una excepción es un objeto derivado de la clase Exception de PHP que se encarga de mantener e
informar de cualquier error producido. Por lo tanto su uso principal es para detener la ejecución del
programa, notificar de errores y ayudar a depurar información.
Una excepción se creará ante una situación anómala en la ejecución del programa que provoca que
este no pueda continuar con normalidad.
Crear y capturar una excepción
Crear una excepción es tan sencillo como utilizar la siguiente sintaxis en el lugar que nos parezca
adecuado:
throw new Exception('Mensaje a mostrar' );
Como podemos ver hemos usado uno de los dos parámetros opciones que se han comentado
anteriormente.
Tras haber lanzado la excepción, necesitamos un mecanismo para capturar esta excepción y poder
mostrar la información que queramos del error y actuar en consecuencia al error. Para ello existe una
estructura de control llamada try/catch. De esta forma dividiremos el manejo de excepciones en dos
partes:
4. Universidad Politécnica Territorial Andrés Eloy Blanco
Programa Nacional de Formación en Informática
Ing. Lissette Torrealba
- Dentro del bloque try se insertará el código que puede provocar una excepción. Ya que este bloque
es el encargado de parar la ejecución del script y pasar el control al bloque 'catch' cuando se
produzca una excepción.
- Dentro de 'catch' introduciremos el código que controlará la excepción. Mostrando el error y
aplicando la funcionalidad necesaria para actuar ante el error.
try {
// Codigo que puede lanzar excepciones }
catch ( Exception $excepcion ) {
// Codigo para controlar la excepcion }
echo "esto si que se ejecuta";
Por lo tanto el uso de las excepciones se basa en dos etapas:
- Cuando ocurra algún error, una excepción será lanzada en un punto del script.
- Para mostrar el error y actuar en consecuencia, es necesario capturar dicha excepción.
Establecimiento de conexiones.
Para establecer una conexión con una base de datos utilizando PDO, debes instanciar un objeto de
la clase PDO pasándole los siguientes parámetros (solo el primero es obligatorio):
Origen de datos (DSN). Es una cadena de texto que indica qué controlador se va a utilizar y a
continuación, separadas por el carácter dos puntos, los parámetros específicos necesarios por el
controlador, como por ejemplo el nombre o dirección IP del servidor y el nombre de la base de
datos.
Puerto
Nombre de usuario con permisos para establecer la conexión.
Contraseña del usuario.
Opciones de conexión, almacenadas en forma de array.
try {
$dsn = "pgsql:host=”localhost”; dbname=”bdprueba
$user=”postgres” // caso de sgbd postgres
$puerto = 5432; // puerto por defecto de postgres
$password = 'clave';
$dbh = new PDO($dsn, $puerto, $user, $password);
} catch (PDOException $e){
echo $e->getMessage();
}
$dbh, significa Database Handle, es el nombre de variable que se suele utilizar para el objeto
PDO.
Registrar datos con PDO
La clase PDOStatement es la que trata las sentencias SQL. Una instancia de PDOStatement se
crea cuando se llama a PDO->prepare(), y con ese objeto creado se llama a métodos
como bindParam() para pasar valores o execute() para ejecutar sentencias. PDO facilita el uso de
5. Universidad Politécnica Territorial Andrés Eloy Blanco
Programa Nacional de Formación en Informática
Ing. Lissette Torrealba
sentencias preparadas en PHP, que mejoran el rendimiento y la seguridad de la aplicación. Cuando
se obtienen, insertan o actualizan datos, el esquema es: PREPARE -> [BIND] -> EXECUTE. Se
pueden indicar los parámetros en la sentencia con un interrogante "?" o mediante un nombre
específico.
Utilizando interrogantes para los valores
// Prepare
$stmt = $dbh->prepare("INSERT INTO Clientes (nombre, ciudad) VALUES (?, ?)");
// Bind
$nombre = "Peter";
$ciudad = "Madrid";
$stmt->bindParam(1, $nombre);
$stmt->bindParam(2, $ciudad);
// Excecute
$stmt->execute();
// Bind
$nombre = "Martha";
$ciudad = "Cáceres";
$stmt->bindParam(1, $nombre);
$stmt->bindParam(2, $ciudad);
// Execute
$stmt->execute();
Utilizando variables para los valores
// Prepare
$stmt = $dbh->prepare("INSERT INTO Clientes (nombre, ciudad) VALUES (:nombre, :ciudad)");
// Bind
$nombre = "Charles";
$ciudad = "Valladolid";
$stmt->bindParam(':nombre', $nombre);
$stmt->bindParam(':ciudad', $ciudad);
// Excecute
$stmt->execute();
// Bind
$nombre = "Anne";
$ciudad = "Lugo";
En la práctica bindValue() se
suele usar cuando se tienen
que insertar datos sólo una
vez, y bindParam() cuando se
tienen que pasar datos
múltiples (desde un array por
ejemplo).
6. Universidad Politécnica Territorial Andrés Eloy Blanco
Programa Nacional de Formación en Informática
Ing. Lissette Torrealba
$stmt->bindParam(':nombre', $nombre);
$stmt->bindParam(':ciudad', $ciudad);
// Execute
$stmt->execute();
Valores mediante un array (siempre array, aunque sólo haya un valor) al método execute():
// Prepare:
$stmt = $dbh->prepare("INSERT INTO Clientes (nombre, ciudad) VALUES (:nombre, :ciudad)");
$nombre = "Luis";
$ciudad = "Barcelona";
// Bind y execute:
if($stmt->execute(array(':nombre'=>$nombre, ':ciudad'=>$ciudad))) {
echo "Se ha creado el nuevo registro!";
}
Es el método execute() el que realmente envía los datos a la base de datos. Si no se llama a execute
no se obtendrán los resultados sino un error.
Una característica importante cuando se utilizan variables para pasar los valores es que se pueden
insertar objetos directamente en la base de datos, suponiendo que las propiedades coinciden con los
nombres de las variables:
class Clientes {
public $nombre;
public $ciudad;
public function __construct($nombre, $ciudad){
$this->nombre = $nombre;
$this->ciudad = $ciudad;
} // ....Código de la clase....
}
$cliente = new Clientes("Jennifer", "Málaga");
$stmt = $dbh->prepare("INSERT INTO Clientes (nombre, ciudad) VALUES (:nombre, :ciudad)");
if($stmt->execute((array) $cliente)){
echo "Se ha creado un nuevo registro!";
Consultar datos con PDO
La consulta de datos se realiza mediante PDOStatement::fetch, que obtiene la siguiente fila de
un conjunto de resultados. Antes de llamar a fetch (o durante) hay que especificar como se quieren
devolver los datos
// FETCH_ASSOC
$stmt = $dbh->prepare("SELECT * FROM Clientes");
7. Universidad Politécnica Territorial Andrés Eloy Blanco
Programa Nacional de Formación en Informática
Ing. Lissette Torrealba
// Especificamos el fetch mode antes de llamar a fetch()
$stmt->setFetchMode(PDO::FETCH_ASSOC);
// Ejecutamos
$stmt->execute();
// Mostramos los resultados
while ($row = $stmt->fetch()){
echo "Nombre: {$row["nombre"]} <br>";
echo "Ciudad: {$row["ciudad"]} <br><br>"; }
// FETCH_OBJ
$stmt = $dbh->prepare("SELECT * FROM Clientes");
// Ejecutamos
$stmt->execute();
// Ahora vamos a indicar el fetch mode cuando llamamos a fetch:
while($row = $stmt->fetch(PDO::FETCH_OBJ)){
echo "Nombre: " . $row->nombre . "<br>";
echo "Ciudad: " . $row->ciudad . "<br>";
PDOStatement::fetchAll(), que devuelve un array con todas las filas devueltas por la base de
datos con las que poder iterar. También acepta estilos de devolución:
// fetchAll() con PDO::FETCH_ASSOC
$stmt = $dbh->prepare("SELECT * FROM Clientes");
$stmt->execute();
$clientes = $stmt->fetchAll (PDO::FETCH_ASSOC);
foreach($clientes as $cliente){
echo $cliente['nombre'] . "<br>";}
// fetchAll() con PDO::FETCH_OBJ
$stmt = $dbh->prepare("SELECT * FROM Clientes");
$stmt->execute();
$clientes = $stmt->fetchAll(PDO::FETCH_OBJ);
foreach ($clientes as $cliente){
echo $cliente->nombre . "<br>";}
Referencias Bibliográficas
Un sitio clave para quienes programamos en PHP orientado a objetos es PHPClasses:
http://www.phpclasses.org