¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. PHP 7
  3. Acceder a las bases de datos
Extrait - PHP 7 Desarrollar un sitio web dinámico e interactivo (2ª edición)
Extractos del libro
PHP 7 Desarrollar un sitio web dinámico e interactivo (2ª edición) Volver a la página de compra del libro

Acceder a las bases de datos

Introducción

1. Información general

La utilización de una base de datos SQL es a menudo esencial para implementar un sitio web dinámico. De hecho, se trata de una forma estándar de almacenamiento de datos útiles para el sitio web:

  • lista de usuarios con sus preferencias,

  • catálogo de productos,

  • seguimiento de las transacciones realizadas.

PHP ofrece soporte nativo para muchas bases de datos, como MySQL, Oracle, Microsoft SQL Server, Informix, Sybase. Asimismo, PHP es compatible con ODBC (Open DataBase Connectivity) y, por tanto, puede acceder a cualquier base de datos compatible con ODBC.

Además, PHP viene con SQLite, una biblioteca que implementa un motor de base de datos SQL. SQLite se puede utilizar para almacenar datos en una base de datos SQL sin tener que implementar la parte del servidor de la base de datos (como es el caso de MySQL, Oracle, etc.).

En este capítulo estudiaremos MySQL, Oracle y SQLite.

Normalmente, cuando se utiliza una base de datos, el script PHP necesita llevar a cabo una o varias de las siguientes tareas:

  • conectarse y desconectarse,

  • leer los datos (una o varias líneas),

  • actualizar los datos (adición, modificación o supresión).

Estas diferentes tareas se tratan en este capítulo.

Se requieren conocimientos mínimos de SQL para abordar este capítulo.

Para los ejemplos que aquí se presentan, suponemos la existencia de una base de datos...

Utilización de MySQL

1. Preámbulo

Desde la versión 7, PHP solo ofrece una extensión para acceder a una base de datos MySQL: MySQLi (prefijo mysqli_).

La extensión MySQL (prefijo mysql_) presente en versiones anteriores de PHP ha sido eliminada en la versión 7.

Ambas extensiones son muy similares en términos de funcionalidad. Muy a menudo ofrecen las mismas funciones, con una sintaxis idéntica o compatible. Salvo excepción, para pasar de usar MySQL a MySQLi, basta con reemplazar el prefijo mysql_ en el nombre de la función por el prefijo mysqli_.

Comenzaremos con la presentación en detalle del uso de la extensión MySQL. A continuación, estableceremos una correspondencia entre la extensión MySQLi y la extensión MySQL, centrándonos en las diferencias más importantes.

La extensión MySQLi se puede usar ya sea como procedimiento o bien en forma de objeto.

En su forma orientada a objeto, la extensión MySQLi ofrece tres clases principales:

mysqli

Conexión entre PHP y MySQL.

mysqli_stmt

Consulta preparada.

mysqli_result

Resultado de la ejecución de una consulta.

Estas diferentes clases ofrecen métodos que permiten efectuar las diferentes acciones (ejecución de una consulta, recuperación del resultado, etc.).

En su forma de procedimiento, la extensión MySQLi ofrece funciones que permiten efectuar las mismas acciones. De manera transparente, varias de estas funciones devuelven o aceptan como parámetros objetos de tipo mysqli o mysqli_result.

En esta obra, presentamos únicamente la forma de procedimiento de la extensión MySQLi.

La extensión MySQLi permite usar las consultas preparadas.

Una consulta preparada es una consulta que contiene parámetros representados por un signo de interrogación (?).

Ejemplos

SELECT * FROM artículo WHERE id = ?  
INSERT INTO artículo(texto,precio) VALUES(?,?) 

Por el contrario, una consulta no preparada es una consulta en la que se especifican todos los valores.

Ejemplos

SELECT * FROM artículo WHERE id = 1 
INSERT INTO artículo(texto,precio) VALUES('Plátanos',10.5) 

Más adelante en este capítulo, veremos cómo ejecutar consultas de lectura y de actualización, primero con consultas no preparadas (véase la sección Utilizar consultas...

Utilización de Oracle

1. Preámbulo

La extensión «Oracle OCI8», al contrario de lo que su nombre pueda hacernos pensar, se puede utilizar para acceder a cualquier versión de Oracle (9i, 10g, 11g y 12c). Esta extensión es muy completa y muy potente; permite utilizar los tipos LOB y ROWID y establecer vínculos entre las variables PHP y las variables en la consulta SQL (concepto de «bind variable»).

2. Entorno NLS

El entorno NLS (National Language Support), utilizado en la ejecución de las consultas, se define por medio de las variables de entorno habituales colocadas en el servidor que ejecuta PHP:

  • NLS_LANG

  • NLS_DATE_FORMAT...

Si estas variables de entorno no se han establecido, se toma el valor predeterminado de Oracle Server.

Esto puede dar lugar a diferencias de funcionamiento de un mismo programa entre dos entornos. Por ejemplo, si recupera en una consulta una columna de tipo DATE, se realiza una conversión en cadena automáticamente (ya que PHP no admite el tipo DATE como tal) según el parámetro NLS_DATE_FORMAT activo; dependiendo de la configuración y el entorno, la cadena recuperada puede tener diferentes formatos (DD/MM/AAAA, DD-MON-YY...).

Problemas similares ocurren con los datos numéricos que también se convierten en una cadena con un separador decimal y un separador de grupo que puede variar en función del entorno.

Si no se controla el entorno, es posible actuar al nivel de código PHP para obtener un código portátil de un entorno a otro:

  • bien efectuando sistemáticamente conversiones explícitas en las instrucciones SQL (TO_CHAR(SYSDATE,’DD/MM/YYYY’), TO_DATE(’31/08/2001’,’DD/MM/YYYY’), TO_CHAR(precio,’9999.99’),TO_NUMBER (’123.45’, ’999.99’) por ejemplo);

  • bien ejecutando, después de cada apertura de sesión, consultas ALTER SESSION (ALTER SESSION SET NLS_DATE_FORMAT = ’DD/MM/YYYY’ o ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ’, ’ por ejemplo).

Volveremos a este tema en la sección Ilustración de problemas relacionados con el entorno NLS.

3. Conexión y desconexión

a. Conexión

La función oci_connect permite abrir una conexión con una base de datos de Oracle.

Sintaxis simplificada

recurso oci_connect(cadena...

Utilización de SQLite

1. Preámbulo

SQLite es una biblioteca que implementa un motor de base de datos SQL.

Se puede utilizar para almacenar datos en una base de datos SQL sin tener que implementar la parte del servidor de la base de datos (como es el caso de MySQL, Oracle, etc.).

SQLite lee y escribe directamente en los archivos de la base de datos.

Para obtener más información sobre SQLite, visite su página web: https://sqlite.org/

PHP ofrece dos extensiones para trabajar con una base de datos SQLite:

  • SQLite para la versión 2 de SQLite.

  • SQLite3 para la versión 3 de SQLite.

La extensión SQLite3 está activada por defecto y la extensión SQLite ya solo está disponible mediante PECL (PHP Extension Community Library).

En este libro, presentaremos únicamente la extensión SQLite3.

SQLite3 es una extensión orientada a objetos que ofrece 3 clases:

  • SQLite3: conexión entre PHP y la base de datos.

  • SQLite3Stmt: gestión de consultas preparadas.

  • SQLite3Result: gestión de resultados de consulta SELECT.

2. Abrir y cerrar una base de datos

a. Abrir una base de datos

La apertura de una base de datos SQLite se efectúa durante la instanciación de un objeto de la clase SQLite3.

Sintaxis del método constructor de la clase SQLite3

SQLite3::_construct (cadena archivo[, entero modo[, cadena cifrado]]) 

Con

archivo

Ruta al archivo de la base de datos.

modo

Modo de apertura de la base de datos:

SQLITE3_OPEN_READONLY: apertura en solo lectura.

SQLITE3_OPEN_READWRITE: apertura en lectura/escritura.

SQLITE3_OPEN_CREATE: creación de la base de datos si no existe.

El valor por defecto es: SQLITE3_OPEN_READWRITE|SQLITE3_OPEN_CREATE.

cifrado

Clave opcional utilizada para el cifrado y descifrado de los datos.

En caso de error, se eleva una excepción.

Ejemplo

 <?php 
// Apertura en lectura/escritura de una base de datos existente. 
$base = new SQLite3('/app/sqlite/diane.dbf'); 
var_dump($base); 
?> 

Resultado

object(SQLite3)#1 (0) { } 

Existe también un método open() que permite abrir una base de datos SQLite en un objeto ya instanciado: este método ofrece la misma sintaxis que el método constructor de la clase.

Las bases de datos abiertas en un script se cierran automáticamente al final del script, salvo por desconexión explícita con el método...

PHP Data Objects (PDO)

PHP Data Objects (PDO) es una extensión, que define una interfaz uniforme para acceder a las bases de datos en PHP. El acceso a una base de datos a través de PDO se efectúa por medio de un controlador que expone las características de la base de datos.

Cabe señalar que PDO no proporciona una capa de abstracción de la base de datos, sino una capa de abstracción del acceso a las bases de datos. Las consultas que escriba deben respetar la sintaxis de la base de datos que utiliza; PDO no reescribe consultas SQL y no emula las características que faltan (a excepción de las consultas con parámetros).

Muchas bases de datos disponen de un controlador PDO, como MySQL, Oracle y SQLite.

PDO es una extensión orientada a objetos compuesta de tres clases:

  • PDO: conexión entre PHP y la base de datos,

  • PDOStatement: consulta preparada y, después de la ejecución, resultado asociado,

  • PDOException: excepción planteada por PDO.

En este capítulo, presentaremos esta extensión utilizando un sencillo ejemplo comentado:

<?php 
// Definición de los parámetros de conexión. 
// La sintaxis de la fuente (Data Source Name o DSN) 
// es específica a cada controlador. 
// Cambiar el valor de la variable $test para comprobar 
// diferentes bases de datos. 
$test = 3; 
switch ($test) { 
 case...

Gestión de los apóstrofos en el texto de las consultas

En el caso del uso de consultas no preparadas, puede plantearse un problema si una cadena de caracteres literal presente en una consulta contiene un apóstrofo.

Ejemplo (inserción en la base de un dato que contiene un apóstrofo)

<?<?php 
// Dato que supone un problema (puede introducirse sin querer 
// en un formulario). 
$texto = "Pomme d'api"; 
$precio = 10; 
// Consulta. 
$consulta = "INSERT INTO artículos(texto,precio)" .  
           "VALUES('$texto',$precio)"; 
echo "$consulta<br />"; 
// Ejecución con MySQL. 
echo "<p><b>MySQL</b><br />"; 
$conexion = mysqli_connect(); 
$ok = mysqli_select_db($conexion, ‘diane'); 
$resultado = mysqli_query($conexion, $consulta); 
echo mysqli_error($conexion),'<br />';  
// MySQL no genera ninguna alerta 
// Ejecución con Oracle. 
echo "<p><b>Oracle</b><br />"; 
$conexion = oci_connect('demeter','demeter','diane'); 
$resultado = oci_execute(oci_parse($conexion,$consulta)); 
// Ejecución con SQLite. 
echo "<p><b>SQLite</b><br />"; 
$base = new SQLite3('/app/sqlite/diane.dbf'); 
$resultado = $base->query($consulta); 
?> > 

Resultado

INSERT INTO artículos(texto,precio) VALUES('Pomme d'api',10) 
 
MySQL 
You have an error in your SQL syntax; check the manual that 
corresponds to your MySQL server version for the right syntax 
to use near 'api',10)' at line 1 
 
Oracle 
Warning: oci_parse(): ORA-01756: quoted 
string not properly terminated in /app/scripts/index.php on line 19 
Warning: oci_execute() expects parameter 1 to be resource, 
boolean given in /app/scripts/index.php on line 19 
 
SQLite 
Warning: SQLite3::query(): Unable to prepare statement: 1, near "api": 
syntax error in /app/scripts/index.php on line 23 

En SQL, el delimitador de cadena de caracteres es el apóstrofo: si una consulta envía la cadena ’Pomme d’api’ a la base de datos...

Ejemplos de integración en formularios

1. Resumen general

Para concluir este capítulo, presentamos algunos ejemplos de acceso a las bases de datos de formularios.

Se proponen cuatro ejemplos:

  • la construcción de una lista de selección en un formulario;

  • un formulario que muestra una lista;

  • un formulario que permite introducir datos en una lista;

  • un formulario de búsqueda y de introducción de datos de tipo "página".

Por motivos de concisión, en estos ejemplos, el control de la introducción de datos está prácticamente ausente, y el formato es muy simple.

Los ejemplos están diseñados para funcionar del mismo modo con MySQL, SQLite y Oracle. Para ello, el acceso a las bases de datos se realiza utilizando varias funciones que se implementan en una biblioteca específica para cada producto. Para hacer funcionar un ejemplo en una base de datos particular, basta con incluir la biblioteca correspondiente.

Las funciones utilizadas para el acceso a las bases de datos son las siguientes:

conexión

Conexión a la base de datos.

seleccionar_artículos

Selección de todos los artículos.

leer_artículo_siguiente

Lectura del artículo siguiente en el resultado de la consulta de selección de todos los artículos.

seleccionar_un_artículo

Selección de un artículo cuyo identificador se pasa como parámetro.

guardar_artículo

Guardar los cambios de un artículo.

guardar_artículos

Guardar las actualizaciones (creación, modificación, eliminación) de una lista de artículos (en asociación con el formulario de publicación de lista).

Sintaxis

booleano conexión(&$conexion,&$error) 
booleano seleccionar_artículos($conexion,&$consulta,&$error)  
mixto leer_artículo_siguiente($conexion,$consulta,&$artículo,&$error) 
booleano seleccionar_un_artículo($conexion,$identificador,&$artículo,&$error) 
booleano guardar_artículo($conexion,$artículo,&$error)  
mixto guardar_artículos($conexion,$líneas,&$error) 

Con:

$conexion

Identificador de la conexión devuelto por la función conexión (parámetro pasado por referencia) y utilizado como entrada para el resto de las funciones (parámetro...