SlideShare una empresa de Scribd logo
1 de 19
Descargar para leer sin conexión
Tema 8
PHP: Acceso a Bases de Datos
Una de las razones por las que más se ha popularizado PHP, como ya comentamos en el tema
anterior, es su posibilidad de conexión con casi todos los tipos de bases de datos.
En este tema vamos a ver algunas nociones de MySQL: instalación y configuración rápida,
organización, etc. La razón de ver MySQL es porque se trata de base de datos más usada con
PHP, incluso se podría decir que es la base de datos “propia” de PHP, pues al parecer, PHP
Group desarrolla en primera instancia para esta base de datos y después migra el trabajo a las
librerías de acceso a otras bases de datos.
Otra librería de acceso a bases de datos interesante es la de acceso a través de ODBC que
nos abre el camino a la conexión a cualquier otro tipo de base de datos de la que no se tenga
acceso “nativo” en PHP. También puede ser interesante usar el acceso ODBC para las bases
de datos de las que se tiene funciones PHP directamente, pues, aunque aparentemente más
complejo y aveces más limitado, el acceso ODBC nos garantiza cierta compatibilidad que
prácticamente nos independiza del SGDB que se use.
Así pues, en este tema vamos a trabajar sobre tres ejemplos de acceso a bases de datos
MySQL y dos ejemplos ODBC en el que podremos trabajar tanto con MySQL como con otras
bases de datos como MS-Access.
8.1. De vuelta con PHP
Vamos en primera instancia a retomar algunos de los ejemplos PHP del tema anterior para ir
calentando motores.
En concreto, con idea de seguir con los ejemplos auto-ilustrativos del Tema 7, vamos a
fusionar el ejemplo generico.php y ejemplos.php de forma que un solo código nos
gestione una plantilla genérica y nos permita elegir y ejecutar los ejemplos de este tema, que a
semejanza del caso anterior están en el directorio:
"C:Archivos de programaApache GroupApachecgi-bintema8"
La plantilla .phtml usada ahora se ha adaptado para este tema: Visualiza a la izquierda el
código, a la derecha un formulario y encima de la tabla el posible resultado producido al invocar
el formulario. La nueva plantilla se llama ahora:
"C:Archivos de programaApache GroupApachehtdocstema8index.phtml"
La idea es la de adaptar Apache para que también pueda tomar como página por defecto de un
sitio Web ese nombre de fichero, cambiando en httpd.conf la siguiente línea:
DirectoryIndex index.html
… por esta otra:
DirectoryIndex index.html index.phtml
Recuerda arrancar Apache.
Tema 8. PHP: Acceso a Bases de Datos
2
Listado 8.1. C:Archivos de programaApache GroupApachehtdocstema8index.phtml
Plantilla de ejemplos del Tema 8.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<?php include "tema8/ejemplos.php"?>
<HTML>
<HEAD>
<TITLE>
<?php titulo()?>
</TITLE>
</HEAD>
<BODY>
<CENTER>
<H1 style="font-weight:bold; font-size:200%; color:blue">
<?php titulo()?>
</H1>
<?php resultado()?>
<TABLE width="100%" border="1" rules="all">
<TR align="center">
<TD>
<B>C&oacute;digo</B><BR>
</TD>
<TD>
<B>Formulario</B><BR>
</TD>
</TR>
<TR valign="top">
<TD>
<?php codigo()?>
</TD>
<TD>
<?php formulario()?>
</TD>
</TR>
</TABLE>
</CENTER>
</BODY>
</HTML>
El esquema es semejante al usado en el tema 7, pero hay que destacar que la función
resultado ha sido sustituida por una formulario y una nueva función resultado debe reflejar en la
parte superior el resultado de enviar el formulario.
La función formulario invocará a una función del mismo nombre que el ejemplo que se esté
visualizando, como antes hacia la función resultado.
El código del nuevo ejemplo ejemplos.php queda así:
Listado 8.2. C:Archivos de programaApache GroupApachecgi-bintema8ejemplos.php
Programa que permite seleccinar uno de los ejemplos del Tema 8.
<SCRIPT language="php">
if (!isset($Ejemplo))
$Ejemplo="Ejemplos";
$Fichero=strToLower("tema8/$Ejemplo.php");
@include_once($Fichero);
if (!function_exists("titulo")) {
function titulo() {
global $Ejemplo;
print($Ejemplo);
}
}
if (!function_exists("resultado")) {
function resultado() {
}
}
function codigo() {
global $Ejemplo;
global $Fichero;
if (@show_source($Fichero)) {
function formulario() {
Tema 8. PHP: Acceso a Bases de Datos
3
global $Ejemplo;
$Ejemplo();
}
}
else
print("¿$Ejemplo.php?");
}
function ejemplos() {
global $REQUEST_URI;
include("tema8/plantillas/ejemplos.html");
}
function opciones() {
$Directorio=openDir(get_cfg_var("include_path")."/tema8/");
while ($Fichero=readDir($Directorio)) {
$Fichero=ucFirst(strToLower($Fichero));
list($Ejem,$Ext)=explode(".",$Fichero);
if ($Ejem AND !strCaseCmp($Ext,"php"))
print("<OPTION>$Ejem</OPTION>n");
}
closeDir($Directorio);
}
</SCRIPT>
A destacar únicamente dos puntos. Lo primero que si la función resultado no existe (porque el
ejemplo no hace nada cuando se envía el formulario), para que no se produzca error al
invocarla, se crea vacía.
Lo segundo, el formulario que debería estar en la función con el mismo nombre que el fichero
(ejemplos() en este caso) no esta en este fichero, sino aparte, en un fichero con extensión
.html, que aunque no es verdaderamente un fichero HTML, puede ser medianamente
interpretado por un navegador o un programa de diseño HTML, de forma que se puede ver y
cambiar independientemente del código, es decir se trata de una plantilla.
Así pues, la función que muestra el formulario queda reducida a declarar como globales todas
las variables que se usen en la plantilla .html e incluirla. Este esquema se repite en todos los
ejemplos de este tema. El directorio que contiene las plantillas .html de los formularios es:
"C:Archivos de programaApache GroupApachecgi-bintema8plantillas"
Puedes ver el aspecto que tienen estas plantillas cargándolas desde tu disco local
directamente (no a través del servidor Apache) con tu navegador.
La plantilla que usamos en este “invocador” de ejemplos es:
Listado 8.3. C:Archivos de … GroupApachecgi-bintema8plantillasejemplos.html
Plantilla formulario para seleccionar ejemplos.
</SCRIPT>
<FORM action="<?=$REQUEST_URI?>" method="POST">
<CENTER>
<LABEL>
<B>Ejemplos:</B><BR>
<SELECT name="Ejemplo">
<?php opciones()?>
</SELECT>
</LABEL><BR>
<INPUT type="submit" value="Mostrar">
</CENTER>
</FORM>
<SCRIPT language="php">
Ahora puedes ver el resultado, invocar a cualquier ejemplo de este tema se hace con la URL:
http://localhost/tema8
Tema 8. PHP: Acceso a Bases de Datos
4
8.2. MySQL
Monty Widenius quiso trabajar con APIs a bajo nivel de mSQL, comprobó que no eran
suficientemente rápidas y decidió crear sus propias APIs MySQL. Así nació MySQL, una base
de datos SQL (Structured Query Language) muy rapida, multi-hebra, multi-usuario y robusta
según sus propios autores.
Se trata, además, de un software gratuito licenciado bajo la General Public License de GNU.
Instalación
El primer paso que debemos dar es descargar la última versión desde http://www.mysql.com. Las
distribuciones de binarios para Win32 siempre han sido “tradicionalmente” shareware. En el
momento de editar estas páginas, se encuentra disponible una versión 3.23.28-gamma
totalmente gratuita.
El segundo paso es la descompresión del paquete y su instalación, ejecutando programa
setup que aparece al descomprimir.
La instalación compacta es suficiente para nuestro caso y para la mayoría de usuarios de
MySQL que lo ejecuten sobre Win32.
Si no le hemos indicado lo contrario el instalador nos habrá creado un directorio C:mysql,
con varios ficheros y subdirectorios. Los importantes son estos tres subdirectorios:
C:mysqldocs
Contiene documentación sobre MySQL. Lo más interesante es el manual, accesible en HTML
desde el fichero C:mysqldocsmanual_toc.html.
C:mysqldata
Por defecto almacena las bases de datos, en un subdirectorio cada una (con el mismo nombre
que la base de datos). La distribución instala por defecto dos, la del sistema del propio servidor
que se llama mysql y otra test, pero esta última está vacía. En subdirectorio correspondiente
a la base de datos del sistema (mysql) se puede apreciar que MySQL guarda tres ficheros por
cada tabla, con el mismo nombre que la tabla pero distintas extensiones: El formato se guarda
en los ficheros .frm, los datos en los .myd y la información para gestionar el acceso por
indices en los .myi. Las tablas de mysql son 5: user, host, db, tables_priv y
columns_priv.
C:mysqlbin
Este directorio guarda los ejecutables: Demonios servidores, clientes, gestores y herramientas
de test, administración y mantenimiento. Algunos de ellos son sólo para Windows NT o sólo
para Windows 9x. El único que de momento nos interesa es winmysqladmin.exe, que lo
ejecutaremos para comprobar la instalación y arrancar el servidor:
WinMySQLadmin
Cuando lo ejecutamos por primera vez nos pregunta por un usuario y clave para establecerlos
como defecto. Esto lo hace por que detecta que no existe el fichero de configuración:
C:windowsmy.ini
En la documentación se explica como incluir distintas opciones en este fichero. Si le damos a
cancelar y no introducimos ningún usuario y clave, creará un fichero my.ini con las opciones
mínimas. No te tiene que preocupar no proporcionar usuario por defecto, pues la base de datos
del sistema (la mysql que hemos visto en el directorio data) viene preparada inicialmente para
Tema 8. PHP: Acceso a Bases de Datos
5
operar con cualquier usuario. Sin embargo el dar a cancelar también implica que no incluya un
enlace directo a winmysqladmin.exe en el menú de inicio que producirá el arranque
automático de este programa al iniciar una sesión en Windows. Puede ser interesante que
copies o muevas ese enlace directo a otro menú, uno propio del MySQL, para poderlo invocar
voluntariamente.
Después, el programa WinMySQLadmin se quedará residente. Lo puedes apreciar por un
semáforo con la luz verde que aparece a la derecha de la barra de tareas. Este semáforo tiene
la luz verde cuando el servidor de MySQL se encuentra en marcha y rojo si está parado. El
programa WinMySQLadmin no es el servidor, sino un programa que sirve para arrancar, parar
y monitorizar al servidor. Éstas son las opciones que aparecen al solicitar el menú contextual
sobre icono del semáforo, además de la opción de parar esta propia herramienta, que no
implica parar el servidor MySQL.
En conclusión, aunque esta herramienta nos permita curiosear el funcionamiento del servidor,
principalmente servirá para poder arrancar y parar el servidor MySQL y comprobar mediante la
luz del semáforo si está en marcha.
Acceso a MySQL
Otro programa llamado simplemente mysql (aparece también e el directorio C:mysqlbin)
es el típico interprete SQL de línea de comandos. Invócalo para ver alguna tabla de la base de
datos del sistema (la mysql):
C:>C:mysqlbinmysql.exe mysql
Ahora prueba a listar la tabla de usuarios y permisos:
mysql> select * from user;
Lo que estas viendo significa algo así como:
• El usuario root tiene todos los privilegios posibles desde la máquina localhost.
• Cualquier usuario desde cualquier máquina no tiene ningún privilegio.
• Cualquier usuario desde localhost tiene todos los privilegios.
• El usuario root desde cualquier máquina tiene todos los privilegios.
• Es posible que aparezca otra fila con el usuario y clave que te pidió WinMySQLadmin.
Acceso a MySQL mediante PHP
Vamos a intentar visualizar la misma tabla de usuarios que hemos visto mediante el interprete
SQL, pero a través de nuestro servidor Apache y un programa PHP. Para ello vamos a ver un
ejemplo de visor de tablas: un formulario recoge máquina, usuario, base de datos y tabla, y
mediante las funciones PHP de acceso a MySQL visualizamos la tabla.
La plantilla del formulario será:
Listado 8.4. C:Archivos de … GroupApachecgi-bintema8plantillasvisor.html
Plantilla formulario para el visor.
</SCRIPT>
<FORM action="<?=$REQUEST_URI?>" method="POST">
<INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>">
<TABLE>
<LABEL><TR>
<TD><B>Host:</B></TD>
<TD><INPUT type="text" name="Host" value="localhost"></TD>
</TR></LABEL>
<LABEL><TR>
Tema 8. PHP: Acceso a Bases de Datos
6
<TD><B>Usuario:</B></TD>
<TD><INPUT type="text" name="Usuario" value="root"></TD>
</TR></LABEL>
<LABEL><TR>
<TD><B>Base de datos:</B></TD>
<TD><INPUT type="text" name="BD"></TD>
</TR></LABEL>
<LABEL><TR>
<TD><B>Tabla:</B></TD>
<TD><INPUT type="text" name="Tabla"></TD>
</TR></LABEL>
<TR><TD colspan="2"><CENTER>
<INPUT type="submit" name="Visualizar" value="Visualizar">
<INPUT type="submit" value="Limpiar"></CENTER>
</TD></TR>
</TABLE>
</FORM>
<SCRIPT language="php">
Lo primero que nuestro programa debe hacer es conectarse a un servidor MySQL en una
máquina $Host como el usuario $Usuario, después seleccionar la base de datos $BD, lanzar
la pregunta SQL que obtendrá la selección de las filas de la tabla $Tabla y por último
interpretar el resultado:
Listado 8.5. C:Archivos de programaApache GroupApachecgi-bintema8visor.php
Visor de tablas MySQL.
<SCRIPT language="php">
function visualizar($Host,$Usuario,$BD,$Tabla) {
if (!mysql_connect($Host,$Usuario))
print("<P>Error al conectar con $Host como $Usuario</P>");
elseif (!mysql_select_db($BD))
print("<P>Error al seleccionar la base de datos $BD</P>");
elseif (!$Cursor=mysql_query("SELECT * FROM $Tabla"))
print("<P>Error al obtener cursor a tabla $Tabla</P>");
else {
print("<TABLE border="1" rules="all">n");
print("<TR>n");
for ($i=0;$i<mysql_num_fields($Cursor);$i++)
print("<TH>".mysql_field_name($Cursor,$i)."</TH>n");
print("</TR>n");
while ($Fila=mysql_fetch_row($Cursor)) {
print("<TR>n");
foreach ($Fila as $Campo) print("<TD>$Campo</TD>n");
print("</TR>n");
}
print("</TABLE><BR>n");
}
}
function resultado() {
global $Visualizar,$Host,$Usuario,$BD,$Tabla;
if (isset($Visualizar)) {
print("<P><B>Host:</B> $Host ");
print("<B>Usuario:</B> $Usuario ");
print("<B>Base de datos:</B> $BD ");
print("<B>Tabla:</B> $Tabla</P>n");
visualizar($Host,$Usuario,$BD,$Tabla);
}
}
function visor() {
global $REQUEST_URI,$Ejemplo;
include("tema8/plantillas/visor.html");
}
</SCRIPT>
La función mysql_connect(), de ser satisfactoria, devuelve un enlace a la base de datos.
Este enlace debería ser pasado a las funciones mysql_select_db() y mysql_query(),
pero ese parámetro es opcional, en caso de no hacerlo, se toma como enlace, la última
conexión hecha, que en nuestro caso se trata de la única conexión hecha.
La función mysql_query() devuelve un recurso, que puede ser interpretado en este caso
como un cursor, del que poder extraer la información requerida en la pregunta. Son varias las
Tema 8. PHP: Acceso a Bases de Datos
7
funciones que pueden extraer información de un recurso devuelto por mysql_query(), y
distintas las formas o estrategias para interpretarlo:
• Mediante la función mysql_fetch_object() se puede obtener un objeto por fila cuyos
atributos son los campos de la tabla.
• Mediante la función mysql_fetch_array() se pude obtener un array por fila cuyas
claves sean los campos de la tabla, sus posiciones o ambas cosas.
• mysql_fecth_row() es un caso particular del anterior, el array siempre esta indexado
por posiciones (empezando por la 0).
• Se puede acceder a cualquier fila y columna de la tabla mediante la función
mysql_result().
Además es posible acceder a otra información sobre la respuesta, como el nombre los campos
de la tabla o que cantidad de filas o columnas hay. En el ejemplo se usan las funciones
myql_num_fields() y mysql_filed_name(). Esto nos permite poder visualizar los
nombres de los campos en la cabecera de la tabla incluso cuando la tabla esta vacía: No
pruebes solo la tabla user de la base de datos mysql, prueba también con una tabla vacía
como tables_priv de la misma base de datos.
8.3. Manejo de bases de datos MySQL desde PHP
Para poder ilustrar gran parte de las posibilidades de edición de las funciones PHP de acceso a
MySQL, vamos a ver dos ejemplos más. El primero para poder crear una base nueva con la
que experimentar (crear tablas, campos, modificarlos, borrar, etc.). El segundo, combinándolo
con el manejo de sesiones nos permitirá editar (añadir, modificar y borrar) fila a fila en una base
de datos.
Gestor de base de datos (manejo de la estructura)
En este ejemplo vamos a usar tres formularios distintos, dependiendo del nivel de atomicidad al
que llevemos la gestión (base de datos, tabla o campo):
Listado 8.6. C:Archivos de … GroupApachecgi-bintema8plantillasgesbd.html
Plantilla formulario para el gestor en gestion a bases de datos.
</SCRIPT>
<FORM action="<?=$REQUEST_URI?>" method="POST">
<INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>">
<INPUT type="hidden" name="Gestion" value="<?=$Gestion?>">
<TABLE>
<LABEL><TR>
<TD><B>Host:</B></TD>
<TD><INPUT type="text" name="Host" value="<?=$Host?>"></TD>
</TR></LABEL>
<LABEL><TR>
<TD><B>Usuario:</B></TD>
<TD><INPUT type="text" name="Usuario" value="<?=$Usuario?>"></TD>
</TR></LABEL>
<LABEL><TR>
<TD><B>Base de datos:</B></TD>
<TD><INPUT type="text" name="BD"></TD>
</TR></LABEL>
<TR><TD colspan="2"><CENTER>
<INPUT type="submit" name="Operacion" value="Crear">
<INPUT type="submit" name="Operacion" value="Conectar">
<INPUT type="submit" name="Operacion" value="Eliminar"></CENTER>
</TD></TR>
</TABLE>
</FORM>
<SCRIPT language="php">
Tema 8. PHP: Acceso a Bases de Datos
8
La variable $Gestion informará de que gestión se lleva a cabo (base de datos, tabla o
columna), mientras $Operacion indica si se debe crear, eliminar, etc.
Listado 8.7. C:Archivos de … GroupApachecgi-bintema8plantillasgestabla.html
Plantilla formulario para el gestor en gestion a tablas.
</SCRIPT>
<FORM action="<?=$REQUEST_URI?>" method="POST">
<INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>">
<INPUT type="hidden" name="Gestion" value="<?=$Gestion?>">
<INPUT type="hidden" name="Host" value="<?=$Host?>">
<INPUT type="hidden" name="Usuario" value="<?=$Usuario?>">
<INPUT type="hidden" name="BD" value="<?=$BD?>">
<TABLE>
<LABEL><TR>
<TD><B>Tabla:</B></TD>
<TD><CENTER><SELECT name="Tabla">
<?php tablas($BD)?>
</SELECT></CENTER></TD>
</TR></LABEL>
<TR><TD colspan="2"><CENTER>
<INPUT type="submit" name="Operacion" value="Cambiar">
<INPUT type="submit" name="Operacion" value="Eliminar"></CENTER>
</TD></TR>
<TR><TD colspan="2"><CENTER><B>o</B></CENTER></TD></TR>
<LABEL><TR>
<TD><B>Tabla:</B></TD>
<TD><INPUT type="text" name="Nueva"></TD>
</TR></LABEL>
<TR><TD colspan="2"><CENTER>
<INPUT type="submit" name="Operacion" value="Crear"></CENTER>
</TD></TR>
</TABLE>
</FORM>
<SCRIPT language="php">
Las variables del formulario anterior en este se mantienen ocultas. La variable $Nueva llevará
el nombre de la tabla si se trata de una operación Crear.
Listado 8.8. C:Archivos de … GroupApachecgi-bintema8plantillasgescampo.html
Plantilla formulario para el gestor en gestion a campos.
</SCRIPT>
<FORM action="<?=$REQUEST_URI?>" method="POST">
<INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>">
<INPUT type="hidden" name="Gestion" value="<?=$Gestion?>">
<INPUT type="hidden" name="Host" value="<?=$Host?>">
<INPUT type="hidden" name="Usuario" value="<?=$Usuario?>">
<INPUT type="hidden" name="BD" value="<?=$BD?>">
<INPUT type="hidden" name="Tabla" value="<?=$Tabla?>">
<TABLE>
<LABEL><TR>
<TD><B>Campo:</B></TD>
<TD><CENTER><SELECT name="Campo">
<?php campos($BD,$Tabla)?>
</SELECT></CENTER></TD>
</TR></LABEL>
<TR><TD colspan="2"><CENTER>
<INPUT type="submit" name="Operacion" value="Eliminar"></CENTER>
</TD></TR>
<TR><TD colspan="2"><CENTER><B>o</B></CENTER></TD></TR>
<LABEL><TR>
<TD><B>Campo:</B></TD>
<TD><INPUT type="text" name="Nuevo"></TD>
</TR></LABEL>
<TR><TD>
<LABEL><INPUT type="radio" name="Tipo" value="INT" checked>Entero</LABEL>
</TD></TR>
<TR><TD>
<LABEL><INPUT type="radio" name="Tipo" value="VARCHAR">Cadena</LABEL>
</TD><TD><CENTER>
Tema 8. PHP: Acceso a Bases de Datos
9
<LABEL>Longitud: <INPUT type="text" name="Longitud" size="2"></LABEL>
</CENTER></TD></TR>
<TR><TD colspan="2"><CENTER>
<INPUT type="submit" name="Operacion" value="Añadir"></CENTER>
</TD></TR>
</TABLE>
</FORM>
<SCRIPT language="php">
A la hora de añadir un campo, las variable $Nuevo y $Tipo aportan el nombre y el tipo
respectivamente. Solo se permiten dos tipos de datos (para simplificar), el entero y la cadena.
En este segundo tipo otra variable $Longitud aporta el número máximo de caracteres.
También por simplificar, no se puede cambiar de tipo un campo, ha de eliminarse y añadirse de
nuevo.
Listado 8.9. C:Archivos de programaApache GroupApachecgi-bintema8gestor.php
Gestor de bases de datos MySQL.
<SCRIPT language="php">
function resultado() {
global $Host,$Usuario,$BD,$Tabla,$Campo;
global $Gestion,$Operacion;
if (isset($Gestion)) { // Si se ha solicitado una gestion ...
if (mysql_connect($Host,$Usuario)) { // se conecta y gestiona
$Gestion=$Gestion($Operacion,$BD,$Tabla,$Campo);
if ($Gestion!="gestionBD") { // Se muestran los datos
print("<P><B>Host:</B> $Host ");
print("<B>Usuario:</B> $Usuario ");
print("<B>Base de datos:</B> $BD ");
if ($Gestion!="gestionTabla")
print("<B>Tabla:</B> $Tabla");
print("</P>n");
}
}
else {
print("<P>Error al conectar con $Host como $Usuario</P>n");
$Gestion="gestionBD";
}
}
else {
$Gestion="gestionBD";
$Host="localhost";
$Usuario="root";
}
}
function gestionBD($Operacion,$BD) { // Para base de datos
switch ($Operacion) {
case "Crear": // - o se crea:
if (!mysql_create_db($BD)) {
print("<P>Error al crear la base de datos $BD</P>n");
return("gestionBD");
}
case "Conectar": // - o entra en la BD
if (!mysql_select_db($BD)) {
print("<P>Error al seleccionar la base de datos $BD</P>n");
return("gestionBD");
}
return("gestionTabla");
case "Eliminar": // - o se elimina
if (!mysql_drop_db($BD))
print("<P>Error al eliminar la base de datos $BD</P>n");
default:
return("gestionBD");
}
}
function tablas($BD) { // Lista las tablas de una BD como opciones
$Cursor=mysql_list_tables($BD);
for ($i=0;$i<mysql_num_rows($Cursor);$i++)
print("<OPTION>".mysql_tablename($Cursor,$i)."</OPTION>n");
}
function gestionTabla($Operacion,$BD,&$Tabla) { // Para tabla
global $Nueva;
if (!mysql_select_db($BD)) { // Entra en la base de datos
print("<P>Error al seleccionar la base de datos $BD</P>n");
Tema 8. PHP: Acceso a Bases de Datos
10
return("gestionBD");
}
if ($Operacion=="Eliminar") { // Elimina tabla o ...
if (!mysql_query("DROP TABLE $Tabla"))
print("<P>Error al eliminar la tabla $Tabla</P>");
return("gestionTabla");
}
if ($Operacion=="Crear") { // ... crea tabla
if (!mysql_query("CREATE TABLE $Nueva (id INT)")) {
print("<P>Error al crear la tabla $Nueva</P>");
return("gestionTabla");
}
$Tabla=$Nueva;
}
return("gestionCampo");
}
function campos($BD,$Tabla) { // Lista los campos de una tabla
$Cursor=mysql_list_fields($BD,$Tabla);
for ($i=0;$i<mysql_num_fields($Cursor);$i++)
print("<OPTION>".mysql_field_name($Cursor,$i)."</OPTION>n");
}
function gestionCampo($Operacion,$BD,$Tabla,$Campo) { // Para campo
global $Nuevo, $Tipo, $Longitud;
if (!mysql_select_db($BD)) { // Entra en la base de datos
print("<P>Error al seleccionar la base de datos $BD</P>n");
return("gestionBD");
}
if ($Operacion=="Eliminar") // Elimina campo o ...
if (!mysql_query("ALTER TABLE $Tabla DROP COLUMN $Campo"))
print("<P>Error al eliminar el campo $Campo</P>");
if ($Operacion=="Añadir") { // ... añade campo
if ($Tipo=="VARCHAR")
$Tipo="$Tipo($Longitud)";
if (!mysql_query("ALTER TABLE $Tabla ADD COLUMN $Nuevo $Tipo"))
print("<P>Error al añadir el campo $Nuevo tipo $Tipo</P>");
}
return("gestionCampo");
}
function gestor() {
global $REQUEST_URI,$Ejemplo,$Gestion;
global $Host,$Usuario,$BD,$Tabla;
if ($Gestion=="gestionCampo") // Seleciona formulario
include("tema8/plantillas/gescampo.html");
elseif ($Gestion=="gestionTabla")
include("tema8/plantillas/gestabla.html");
else
include("tema8/plantillas/gesbd.html");
}
</SCRIPT>
La variable $Gestion almacena el nombre de la función que debe realizar la gestión:
gestionBD(), gestionTabla(), o gestionCampo(). Todas las gestiones son llamadas
con el máximo de parámetros, aunque a algunas no les hace falta tantos.
La función gestionBD() crea y destruye tablas con las funciones mysql_create_db() y
mysql_drop_db() respectivamente.
La función gestionTabla() destruye y crea tablas con las instrucciones DROP TABLE … y
CREATE TABLE … de SQL.
La función gestionCampo() elimina y añade campos con la instrucción ALTER TABLE … de
SQL.
Las funciones tablas() y campos() listan en los formularios, como opciones, las tablas de
una base de datos y los campos de una tabla. Para ello utilizan funciones para extraer
información sobre la estructura de la base de datos como mysql_list_tables() y
mysql_list_fields().
Tema 8. PHP: Acceso a Bases de Datos
11
Puedes probarlo creando nuevas bases de datos y/o eliminándolas después. Además puedes
verificar los cambios que produces con el interprete de SQL (mysql) o con el visor del ejemplo
anterior.
Editor de base de datos (manejo de los datos)
Vamos a ver otro ejemplo con el que poder rellenar de datos las bases de datos creadas con el
anterior. La edición la haremos por fila, pudiendo pasar de una fila a otra para su edición. Esto
supone establecer sesiones que nos guarden información sobre que fila de que tabla y base de
datos estamos editando. El directorio de datos para las sesiones es, como en otros temas
anteriores, el subdiretorio datos:
C:Archivos de programaApache GroupApachecgi-bintema8datos
La edición consistirá en modificar o borrar la fila actual o añadir una nueva al final, por esa
razón, siempre se dejará editar una fila de más en blanco al final de la tabla.
Las plantillas formulario para este ejemplo son dos, una para seleccionar una tabla y otra para
editar una fila:
Listado 8.10. C:Archivos de … GroupApachecgi-bintema8plantillaseditabla.html
Plantilla formulario para el editor en selección de tabla.
</SCRIPT>
<FORM action="<?=$REQUEST_URI?>" method="POST">
<INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>">
<TABLE>
<LABEL><TR>
<TD><B>Host:</B></TD>
<TD><INPUT type="text" name="Host" value="<?=$Host?>"></TD>
</TR></LABEL>
<LABEL><TR>
<TD><B>Usuario:</B></TD>
<TD><INPUT type="text" name="Usuario" value="<?=$Usuario?>"></TD>
</TR></LABEL>
<LABEL><TR>
<TD><B>Base de datos:</B></TD>
<TD><INPUT type="text" name="BD" value="<?=$BD?>"></TD>
</TR></LABEL>
<LABEL><TR>
<TD><B>Tabla:</B></TD>
<TD><INPUT type="text" name="Tabla" value="<?=$Tabla?>"></TD>
</TR></LABEL>
<TR><TD colspan="2"><CENTER>
<INPUT type="submit" name="Operacion" value="Editar"></CENTER>
</TD></TR>
</TABLE>
</FORM>
<SCRIPT language="php">
Listado 8.11. C:Archivos de … GroupApachecgi-bintema8plantillasedifila.html
Plantilla formulario para el editor en edición de fila.
</SCRIPT>
<FORM action="<?=$REQUEST_URI?>" method="POST">
<INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>">
<TABLE>
<?php campos($Cursor,$Fila)?>
<TR><TD colspan="2"><CENTER>
<INPUT type="submit" name="Operacion" value="<?=boton('Añadir')?>">
<INPUT type="submit" name="Operacion" value="<?=boton('Modificar')?>">
<INPUT type="submit" name="Operacion" value="<?=boton('Borrar')?>">
</CENTER></TD></TR>
<TR><TD colspan="2"><CENTER>
<INPUT type="submit" name="Operacion" value="<?=boton('<<')?>">
<INPUT type="submit" name="Operacion" value="<?=boton('<')?>">
<INPUT type="submit" name="Operacion" value="Salir">
Tema 8. PHP: Acceso a Bases de Datos
12
<INPUT type="submit" name="Operacion" value="<?=boton('>')?>">
<INPUT type="submit" name="Operacion" value="<?=boton('>>')?>">
</CENTER></TD></TR>
</TABLE>
</FORM>
<SCRIPT language="php">
La función boton() determina si el botón queda habilitado o deshabilitado. Lamentablemente,
esta funcionalidad de habilitar o deshabilitar controles no la reflejan correctamente todos los
navegadores.
El código es el siguiente:
Listado 8.12. C:Archivos de programaApache GroupApachecgi-bintema8editor.php
Editor de bases de datos MySQL.
<SCRIPT language="php">
session_save_path("../../cgi-bin/tema8/datos"); // Antes que nada:
session_start(); // Inicia o restablece sesion:
if (!sizeof($HTTP_SESSION_VARS)) { // Si inicia, da valores
$Host="localhost"; // iniciales a Host y
$Usuario="root"; // Usuario y registra
session_register("Host","Usuario"); // todas las variables a
session_register("BD","Tabla","Fila"); // conservar en sesion
}
else // Si restablece, ...
foreach ($HTTP_POST_VARS as $Variable => $Valor)
if (session_is_registered($Variable)) // sobrescribe con los
${$Variable}=$Valor; // valores de formulario
function resultado() {
global $Operacion,$Host,$Usuario;
global $BD,$Tabla,$Cursor;
if (isset($Operacion) AND $Operacion!="Salir")
if (!mysql_connect($Host,$Usuario))
print("<P>Error al conectar con $Host como $Usuario</P>n");
elseif (!mysql_select_db($BD))
print("<P>Error al seleccionar la base de datos $BD</P>");
elseif (!$Cursor=mysql_query("SELECT * FROM $Tabla"))
print("<P>Error al obtener cursor a tabla $Tabla</P>");
else {
print("<P><B>Host:</B> $Host "); // Informa de conexion,
print("<B>Usuario:</B> $Usuario "); // base de datos y
print("<B>Base de datos:</B> $BD "); // tabla con la que
print("<B>Tabla:</B> $Tabla</P>n"); // operar
return;
}
$Operacion="Salir";
}
function campos($Cursor,$Fila) { // Muestra los campos de la fila
$Tope=mysql_num_rows($Cursor); // corespondiente en formulario:
print("<TR><TD colspan="2 "><CENTER>".($Fila+1));
print(" de ".$Tope."</CENTER></TD></TR>n");
for ($i=0;$i<mysql_num_fields($Cursor);$i++) {
$Campo=mysql_field_name($Cursor,$i);
print("<TR><TD><B>$Campo: </B></TD><TD><CENTER>");
print("<INPUT type="text" name="_${Campo}_"");
if ($Fila<$Tope)
print(" value="".mysql_result($Cursor,$Fila,$i).""");
print("></TD></CENTER></TD></TR>n");
}
}
function boton($Tipo) { // Determina que botones deben
global $Cursor,$Fila; // o no estar deshabilitados.
print("$Tipo");
switch ($Tipo) {
case "Añadir";
if ($Fila==mysql_num_rows($Cursor))
return;
break;
case "<":
case "<<":
if ($Fila>0)
return;
break;
Tema 8. PHP: Acceso a Bases de Datos
13
case "Modificar":
case "Borrar":
case ">":
case ">>":
if ($Fila<mysql_num_rows($Cursor))
return;
}
print("" disabled "");
}
function operar($Operacion,&$Cursor,$Tabla,&$Fila) {
switch ($Operacion) { // Determina, segun la operacion,
case "Salir": // incrementar o decrementar la
return(FALSE); // fila y hacer la operacion
case "<": // corespondiente.
if (--$Fila>=0) return(TRUE);
case "Editar":
case "<<":
$Fila=0;
return(TRUE);
case ">":
if (++$Fila<=mysql_num_rows($Cursor)) return(TRUE);
case ">>":
$Fila=mysql_num_rows($Cursor);
return(TRUE);
case "Modificar":
case "Borrar":
if ($Fila==mysql_num_rows($Cursor)) return(TRUE);
}
$Operacion($Cursor,$Tabla,$Fila);
if (!$Cursor=mysql_query("SELECT * FROM $Tabla"))
print("<P>Error al obtener cursor a tabla $Tabla</P>");
return(TRUE);
}
function añadir($Cursor,$Tabla,$Fila) { // Añade una fila
global $HTTP_POST_VARS;
for ($i=0;$i<mysql_num_fields($Cursor);$i++) {
if ($i>0) $Valores.=",";
$Campo=mysql_field_name($Cursor,$i);
$Tipo=mysql_field_type($Cursor,$i);
if (strToLower($Tipo)=="string") $Valores.="'";
$Valores.=$HTTP_POST_VARS["_${Campo}_"];
if (strToLower($Tipo)=="string") $Valores.="'";
}
if (!mysql_query("INSERT INTO $Tabla VALUES($Valores)"))
print("<P>Error añadiendo los valores:<BR>($Valores)</P>");
}
function modificar($Cursor,$Tabla,$Fila) { // Cambia una fila
global $HTTP_POST_VARS;
for ($i=0;$i<mysql_num_fields($Cursor);$i++) {
if ($i>0) {
$Nuevos.=",";
$Viejos.=" AND ";
}
$Campo=mysql_field_name($Cursor,$i);
$Nuevos.="$Campo=";
$Viejos.="$Campo=";
$Tipo=mysql_field_type($Cursor,$i);
if (strToLower($Tipo)=="string") {
$Nuevos.="'";
$Viejos.="'";
}
$Nuevos.=$HTTP_POST_VARS["_${Campo}_"];
$Viejos.=mysql_result($Cursor,$Fila,$i);
if (strToLower($Tipo)=="string") {
$Nuevos.="'";
$Viejos.="'";
}
}
if (!mysql_query("UPDATE $Tabla SET $Nuevos WHERE $Viejos"))
print("<P>Error al sustituir por los valores:<BR>$Nuevos</P>");
}
function Borrar($Cursor,$Tabla,$Fila) { // Elimina una fila
for ($i=0;$i<mysql_num_fields($Cursor);$i++) {
if ($i>0) $Valores.=" AND ";
$Campo=mysql_field_name($Cursor,$i);
$Valores.="$Campo=";
Tema 8. PHP: Acceso a Bases de Datos
14
$Tipo=mysql_field_type($Cursor,$i);
if (strToLower($Tipo)=="string") $Valores.="'";
$Valores.=mysql_result($Cursor,$Fila,$i);
if (strToLower($Tipo)=="string") $Valores.="'";
}
if (!mysql_query("DELETE FROM $Tabla WHERE $Valores"))
print("<P>Error al borrar los valores:<BR>$Valores</P>");
}
function editor() {
global $REQUEST_URI,$Ejemplo;
global $Operacion,$Host,$Usuario; // Opera y determina a
global $Cursor,$BD,$Tabla,$Fila; // que formulario volver:
if (operar($Operacion,$Cursor,$Tabla,$Fila))
include("tema8/plantillas/edifila.html");
else
include("tema8/plantillas/editabla.html");
}
</SCRIPT>
Lo primero que hace el código es gestionar la sesión. Esta premura se justifica porque por
defecto las sesiones se establecen por medio de cookies que deben ser introducidas como
cabeceras de los mensajes de respuesta, así que, como vimos en el tema anterior, la gestión
de una sesión debe realizarse antes de que el interprete PHP empiece a enviar el cuerpo del
mensaje de respuesta.
La función session_start() empieza una sesión si no existía, en caso contrario la reasume.
Reasumirla significa restablecer los valores de las variables registradas en anteriores
conexiones de esa misma sesión.
Así pues, si no existe ninguna variable vinculada a la sesión ($HTTP_SESSION_VARS) significa
que es la primera conexión de la sesión y que todavía no se ha registrado ninguna variable. En
este caso registraremos todas las variables necesarias previa inicialización de las que nos
interesen.
Si no se trata de la primera conexión de la sesión, es posible que los valores de las variables
registradas en la sesión (valores que tenían en la última conexión) entren en conflicto con los
valores enviados por formulario (en nuestro caso por método POST). El problema es que
valores asumen las variables globales PHP, el procedente de la sesión (el que perdura de la
conexión anterior) o el que proviene del formulario.
La directiva de configuración variables_order del fichero php.ini configura en que orden
pasan los valores a las variables globales. Los valores de las variables globales predefinidas
provienen de cinco posibles fuentes método GET, método POST, cookies, variables de entorno
o sesión. En principio podríamos utilizar esta directiva para indicar que, en caso de conflicto,
nos interesa más los valores introducidos por formulario (método POST) que los procedentes
de la sesión.
Esto significaría que PHP debería leer primero las variables registradas en la sesión y después
las que vienen en la petición. Pero pensemos como obtiene PHP los valores de las variables de
sesión: los obtiene de un fichero asociado al identificador de sesión donde guardó los valores al
terminar la última conexión de la sesión. El identificador de sesión es un nombre único para
cada sesión que el navegador y PHP se pasan mediante cookies y/o variables ocultas en
formularios. Puedes comprobarlo al visualizar el código HTML desde tu navegador y buscando
en el formulario de este ejemplo, por defecto la variable se llama PHPSESSID. PHP incluye por
defecto esta variable en cualquier formulario que genere durante una sesión como alternativa a
que el usuario desactive el sistema de cookies.
En resumen, no se puede adelantar la valoración de las variables registradas en una sesión al
paso de variables por cookies, método GET o método POST, pues se usa una variable pasada
por alguno o algunos de estos tres métodos para identificar a la propia sesión.
Así pues nos toca a nosotros mismos reescribir los valores de las variables globales que entren
en conflicto por tener valor de procedencia sesión y procedencia formulario a la vez. Esto no es
Tema 8. PHP: Acceso a Bases de Datos
15
complicado, pues tenemos los valores claramente identificados por procedencia en los arrays
$HTTP_COOKIE_VARS, $HTTP_POST_VARS, $HTTP_GET_VARS y $HTTP_SESSION_VARS.
La función campos() crea entradas del formulario con los campos de la fila en edición, si ésta
es la última fila (la fila de más para añadir) las entradas quedan en blanco. Las variables
asociadas a las entradas de texto tiene el mismo nombre que el campo de la tabla pero con un
carácter _ al principio y al final, por si el nombre del campo coincide con alguna variable ya
usada.
La función operar() ajusta el nuevo valor para la fila y en los casos de Añadir, Modificar
y Borrar, llama a la función del mismo nombre y luego vuelve a pedir el cursor para que
refleje los cambios.
Las funciones añadir(), modifica() y borrar() hacen uso de las instrucciones SQL
INSER INTO …, UPDATE … y DELETE FROM …. Añadir() y modificar() utilizan el array
$HTTP_POST_VARS para obtener los valores de los campos enviados por formulario de las
variables _campo_ correspondientes.
8.4. ODBC
Open Data Base Connection es un estándar que permite tratar de forma genérica las
conexiones a bases de datos SQL. Cada fabricante de sistemas de bases de datos debe
facilitar el controlador correspondiente para que a través de este se pueda conectar a sus
bases de datos.
Como cada sistema de base de datos crea, organiza y en general gestiona sus bases de datos
de forma propia, ODBC solo proporciona funcionalidades genéricas a la mayoría de los
sistemas, dejando fuera muchas operaciones “propias” para cada base de datos y al revés,
pudiendo proporcionar funciones que no tienen efecto en algunos sistemas en concreto. A
pesar de ello resulta muy útil e interesante, pues fusiona, por de alguna forma decirlo, todos los
tipos de accesos a bases de datos en uno.
Para ver todos los controladores instalados que dispones en tu máquina, ves al panel de
control y abre el icono “ODBC” u “ODBC de 32 bits”, los controladores suelen llevar en su
propio nombre una descripción de para qué sistema de base de datos están diseñados.
Con ODBC, en vez de conectarse a una base de datos, hay que conectarse a una fuente de
datos (Data Source). Estas fuentes de datos no son más que una descripción de cómo
conectarse a una verdadera base de datos (con que controlador, a que base de datos, con que
usuario, etc.). Estas descripciones aparecen en la misma ventana de los controladores ODBC
como DSN (Data Source Name), y las hay de tres tipos, generales a sistema, propias del
usuario o descritas en un fichero.
Comprueba si ya tiene disponible alguna DSN a la que conectarte mediante ODBC.
MySQL a través de ODBC
MySQL también tiene sus controladores ODBC, puedes descargarlos de MySQL, en el
momento de escribir este tema la última versión para Windows 9x es la 2.50.36.
El instalador es en realidad un instalador de controladores ODBC genérico que Microsoft
proporciona a los fabricantes de sistemas de bases de datos para que distribuyan sus
controladores. Al descomprimir e instalar nos aparecerá la ventana de gestión de Data Sources
por si queremos añadir una DSN. El instalador ya ha introducido como ejemplo una llamada
sample-MySQL pero conecta con una base de datos test que posiblemente sigamos teniendo
vacía, podemos modificar esta para crear la nuestra.
Tema 8. PHP: Acceso a Bases de Datos
16
En cualquier caso (nueva o modificada), nosotros vamos a obtener una DSN con el nombre
Tema8-ODBC-Mysql que conectará con el controlador ODBC de MySQL a una base de datos
en localhost llamada Tema8 con el usuario root.
Si no tienes una base de datos MySQL que se llame así (Tema8) créala con el ejemplo del
gestor y rellénala con algún dato con el ejemplo editor, pues la vamos a usar en el siguiente
ejemplo.
Para comprobar el controlador ODBC de MySQL está correctamente instalado y que nuestra
DSN está bien definida, llama al programa admndemo.exe que te habrá aparecido al
descomprimir el instalador del controlador.
Lo primero que te pide al arrancar es que le indiques con que DSN conectar. Selecciona
nuestra DSN Tema8-ODBC-MySQL. Luego te aparecerá una ventana dividida en dos paneles.
En el panel superior puedes escribir cualquier instrucción SQL (un SELECT será lo mas facil).
En la barra de menús seleccionamos el menú Command seleccionamos la opción Execute y la
instrucción SQL debe ejecutarse sobre nuestra base de datos Tema8.
Visor ODBC
Vamos a modificar el ejemplo visor para que en vez de conectar directamente con bases de
datos MySQL lo haga a través de ODBC. Le llamaremos odbc precisamente.
La nueva plantilla de formulario es:
Listado 8.13. C:Archivos de … GroupApachecgi-bintema8plantillasodbc.html
Plantila formulario para el visor ODBC.
</SCRIPT>
<FORM action="<?=$REQUEST_URI?>" method="POST">
<INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>">
<TABLE>
<LABEL><TR>
<TD><B>DSN ODBC:</B></TD>
<TD><INPUT type="text" name="DSN" value="<?=$DSN?>"></TD>
</TR></LABEL>
<LABEL><TR>
<TD><B>Usuario:</B></TD>
<TD><INPUT type="text" name="Usuario" value="<?=$Usuario?>"></TD>
</TR></LABEL>
<LABEL><TR>
<TD><B>Tabla:</B></TD>
<TD><INPUT type="text" name="Tabla" value="<?=$Tabla?>"></TD>
</TR></LABEL>
<TR><TD colspan="2"><CENTER>
<INPUT type="submit" name="Visualizar" value="Visualizar">
<INPUT type="submit" value="Limpiar"></CENTER>
</TD></TR>
</TABLE>
</FORM>
<SCRIPT language="php">
El código queda más sencillo todavía que el del visor:
Listado 8.14. C:Archivos de programaApache GroupApachecgi-bintema8odbc.php
Visor de tablas a través de ODBC.
<SCRIPT language="php">
function titulo() {
print("Visor ODBC");
}
function visualizar($DSN,$Usuario,$Tabla) {
print("<P>");
if ($DSN) print("<B>DSN ODBC:</B> $DSN ");
if ($Usuario) print("<B>Usuario:</B> $Usuario ");
Tema 8. PHP: Acceso a Bases de Datos
17
if ($Tabla) print("<B>Tabla:</B> $Tabla");
print("</P>n");
if (!$Conexion=odbc_connect($DSN,$Usuario,""))
print("<P>Error al conectar con $DSN como $Usuario</P>");
elseif (!$Cursor=odbc_exec($Conexion,"SELECT * FROM $Tabla"))
print("<P>Error al obtener cursor a tabla $Tabla</P>");
else {
odbc_result_all($Cursor,"border="1" rules="all"");
print("<BR>n");
}
}
function resultado() {
global $Visualizar,$DSN,$Usuario,$Tabla;
if (isset($Visualizar))
visualizar($DSN,$Usuario,$Tabla);
else
$DSN=$Usuario=$Tabla=$Visualizar;
}
function odbc() {
global $REQUEST_URI,$Ejemplo,$DSN,$Usuario,$Tabla;
include("tema8/plantillas/odbc.html");
}
</SCRIPT>
La función odbc_connect() conecta con la DSN que se le indique.
La función odbc_exec() ejecuta una instrucción SQL. Necesita forzosamente de la conexión
devuelta por odbc_connect().
La función odbc_result_all() imprime el resultado de la consulta SQL en formato tabla HTML, la
cadena que acompaña al cursor como parámetro proporciona los atributos para la etiqueta
TABLE.
Visualiza tablas de la base de datos Tema8 a través de la DSN Tema8-ODBC-MySQL mediante
este ejemplo.
Si dispones de MS-Access, prueba a crear una base de datos, créale una DSN (desde la
ventana de controladores de ODBC que obtienes a través del panel de control se pueden
añadir DSN nuevas) y visualiza sus tablas con este visor PHP de ODBC.
Migración de unos a otros sistemas de bases de datos
Como último ejemplo vamos a ver como pasar una tabla (estructura y datos) de una base de
datos a otra, con independencia de sus sistemas de bases de datos mediante una DNS de
origen y otra de destino.
La plantilla a utilizar es:
Listado 8.15. C:Archivos de … GroupApachecgi-bintema8plantillasmigrador.html
Plantila formulario para el migrador.
</SCRIPT>
<FORM action="<?=$REQUEST_URI?>" method="POST">
<INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>">
<TABLE>
<TR><TD colspan="2">
<CENTER>Migrar de ...</CENTER>
</TD></TR>
<LABEL><TR>
<TD><B>DSN ODBC:</B></TD>
<TD><INPUT type="text" name="De_DSN" value="<?=$De_DSN?>"></TD>
</TR></LABEL>
<LABEL><TR>
<TD><B>Usuario:</B></TD>
<TD><INPUT type="text" name="De_Usuario" value="<?=$De_Usuario?>"></TD>
</TR></LABEL>
<LABEL><TR>
Tema 8. PHP: Acceso a Bases de Datos
18
<TR><TD colspan="2">
<CENTER>... a ...</CENTER>
</TD></TR>
<TD><B>DSN ODBC:</B></TD>
<TD><INPUT type="text" name="A_DSN" value="<?=$A_DSN?>"></TD>
</TR></LABEL>
<LABEL><TR>
<TD><B>Usuario:</B></TD>
<TD><INPUT type="text" name="A_Usuario" value="<?=$A_Usuario?>"></TD>
</TR></LABEL>
<TR><TD colspan="2">
<CENTER>... la ...</CENTER>
</TD></TR>
<LABEL><TR>
<TD><B>Tabla:</B></TD>
<TD><INPUT type="text" name="Tabla" value="<?=$Tabla?>"></TD>
</TR></LABEL>
<TR><TD colspan="2"><CENTER>
<INPUT type="submit" name="Migrar" value="Migrar">
<INPUT type="submit" value="Limpiar"></CENTER>
</TD></TR>
</TABLE>
</FORM>
<SCRIPT language="php">
Lo que el código de este ejemplo hace es: conectar con la DSN origen, obtener el cursor de la
tabla origen, conectar con la DSN destino, extraer información de la estructura de la tabla
origen y crear una tabla en destino como la origen, y por último copiar los datos obtenidos del
cursor de la tabla origen a la tabla destino. Veamos, pues, el código:
Listado 8.16. C:Archivos de programaApache GroupApachecgi-bintema8migrador.php
Migrador de tablas a través de ODBC.
<SCRIPT language="php">
function migrar($De_DSN,$De_Usuario,$A_DSN,$A_Usuario,$Tabla) {
if (!$Origen=odbc_connect($De_DSN,$De_Usuario,""))
print("<P>Error al conectar con $De_DSN como $De_Usuario</P>");
elseif (!$Cursor=odbc_exec($Origen,"SELECT * FROM $Tabla"))
print("<P>Error al obtener cursor a tabla $Tabla</P>");
elseif (!$Destino=odbc_connect($A_DSN,$A_Usuario,""))
print("<P>Error al conectar con $A_DSN como $A_Usuario</P>");
else {
extraerDefinicionCampos($Cursor,$Definicion,$Formatos);
if (odbc_exec($Destino,"CREATE TABLE $Tabla ($Definicion)"))
copiaFilas($Cursor,$Formatos,$Destino,$Tabla);
else
print("<P>Error creando la tabla $Tabla con:<BR>($Definicion)</P>");
}
}
function extraerDefinicionCampos($Cursor,&$Definicion,&$Formatos) {
for ($i=1;$i<=odbc_num_fields($Cursor);$i++) {
if ($i>1) $Definicion.=",";
$Definicion.=odbc_field_name($Cursor,$i);
$Tipo=odbc_field_type($Cursor,$i);
$Definicion.=" ".$Tipo;
if (strToLower($Tipo)=="varchar") {
$Definicion.="(".odbc_field_len($Cursor,$i).")";
$Formatos[]="'%s'";
}
else
$Formatos[]="%d";
}
}
function copiaFilas($Cursor,$Formatos,$Destino,$Tabla) {
for ($i=1;$i<=odbc_num_rows($Cursor);$i++) {
if (odbc_fetch_into($Cursor,$i,$Fila)) {
foreach ($Fila as $j => $Campo) {
if ($j==0)
$Valores=sprintf($Formatos[$j],$Campo);
else
$Valores.=",".sprintf($Formatos[$j],$Campo);
}
if (!odbc_exec($Destino,"INSERT INTO $Tabla VALUES($Valores)"))
print("<P>Error añadiendo los valores:<BR>($Valores)</P>");
Tema 8. PHP: Acceso a Bases de Datos
19
}
else
print("<p>Error al leer fila $i</P>");
}
}
function resultado() {
global $Migrar,$De_DSN,$De_Usuario,$A_DSN,$A_Usuario,$Tabla;
if (isset($Migrar))
migrar($De_DSN,$De_Usuario,$A_DSN,$A_Usuario,$Tabla);
else
$De_DSN=$De_Usuario=$A_DSN=$A_Usuario=$Tabla=$Migrar;
}
function migrador() {
global $REQUEST_URI,$Ejemplo,$Tabla;
global $De_DSN,$De_Usuario,$A_DSN,$A_Usuario;
include("tema8/plantillas/migrador.html");
}
</SCRIPT>
La función extraerDefinicionCampos() obtiene información de la estructura de la tabla
(nombres y tipos de sus campos) a través de as funciones odbc_num_fields(),
odbc_field_name(), odbc_field_type() y odbc_field_len() y la devuelve en la
cadena $Definicion (usada para crear la tabla) y en el array $Formatos donde se guarda
los formatos %d o ’%s’ según sea el campo entero o cadena (No estamos contemplando más
tipos de datos en los ejemplos de este tema).
La función copiaFilas() recorre todas las filas (odbc_num_rows()) mediante la función
odbc_fetch_into() que pasa la fila a un array que es compuesto con los formatos
correspondientes para enviar en una instrucción SQL INSER INTO ….
Para probarlo créate una base de datos MS-Access vacía llamada Tema8. Si no dispones de
MS-Access, en el directorio datos (donde se guarda la información de las sesiones) tienes una.
Crea una DSN con el controlador ODBC de Access llamada Tema8-ODBC-Access para
acceder a la base de datos vacía que has creado. Ahora ejecuta el ejemplo y pasa todas tus
tablas de la base de datos Tema8 de MySQL a la nueva de Access a través de las DSN
Tema8-ODBC-MySQL y Tema8-ODBC-Access. Abre la base de datos en Access y comprueba
la migración. Si no dispones de Access usa el visor ODBC del ejemplo anterior.
8.5. Combinando ejemplos.
Hemos terminado el tema habiendo creado una serie de herramientas que a través de Web nos
van a permitir manipular datos en cualquier sistema de base de datos del que dispongamos su
controlador ODBC, apoyándonos si es necesario en tablas que nos creemos o migremos a
MySQL de forma temporal.
Por ejemplo, si nos creamos la DSN Tema8-ODBC-Texto con el controlador ODBC de texto y
vinculándolo a un directorio cualquiera (o creando uno vacío para tal menester), podemos
hacar tablas en MySQL, pasarlas a texto a través del nuevo DSN y para consultarlas podemos
usar el visor ODBC.

Más contenido relacionado

La actualidad más candente

Taller plataformas tecnológicas ORACLE MSDOS Y UNIX
Taller plataformas tecnológicas ORACLE MSDOS Y UNIXTaller plataformas tecnológicas ORACLE MSDOS Y UNIX
Taller plataformas tecnológicas ORACLE MSDOS Y UNIXRichard Eliseo Mendoza Gafaro
 
Tutorial de cómo crear una pagina web
Tutorial de cómo crear una pagina webTutorial de cómo crear una pagina web
Tutorial de cómo crear una pagina webSamuel Reyes
 
Tutorial php basico
Tutorial php basicoTutorial php basico
Tutorial php basicoYo ♥ Tacna
 
Sesion Nº 03 Tecnologias Web I Instalación Y Configuración Del Servidor A...
Sesion Nº 03   Tecnologias Web I   Instalación Y Configuración Del Servidor A...Sesion Nº 03   Tecnologias Web I   Instalación Y Configuración Del Servidor A...
Sesion Nº 03 Tecnologias Web I Instalación Y Configuración Del Servidor A...Edgar A. Cruz Huaman
 
Manual de instalación drupal 7.2 mejorado Universidad de Los Andes
Manual de instalación drupal 7.2 mejorado Universidad de Los AndesManual de instalación drupal 7.2 mejorado Universidad de Los Andes
Manual de instalación drupal 7.2 mejorado Universidad de Los AndesBrox Technology
 
Instalación básica de php mybibli (pmb)
Instalación básica de php mybibli (pmb)Instalación básica de php mybibli (pmb)
Instalación básica de php mybibli (pmb)Danilo_01
 
Documentacion Final Proyecto UNIX
Documentacion Final Proyecto UNIXDocumentacion Final Proyecto UNIX
Documentacion Final Proyecto UNIXMoisesAlvarez38
 
05 Php. Configuracion De Php
05 Php. Configuracion De Php05 Php. Configuracion De Php
05 Php. Configuracion De PhpJosé M. Padilla
 

La actualidad más candente (10)

Php curso02
Php   curso02Php   curso02
Php curso02
 
Taller plataformas tecnológicas ORACLE MSDOS Y UNIX
Taller plataformas tecnológicas ORACLE MSDOS Y UNIXTaller plataformas tecnológicas ORACLE MSDOS Y UNIX
Taller plataformas tecnológicas ORACLE MSDOS Y UNIX
 
Comodo Backup
Comodo BackupComodo Backup
Comodo Backup
 
Tutorial de cómo crear una pagina web
Tutorial de cómo crear una pagina webTutorial de cómo crear una pagina web
Tutorial de cómo crear una pagina web
 
Tutorial php basico
Tutorial php basicoTutorial php basico
Tutorial php basico
 
Sesion Nº 03 Tecnologias Web I Instalación Y Configuración Del Servidor A...
Sesion Nº 03   Tecnologias Web I   Instalación Y Configuración Del Servidor A...Sesion Nº 03   Tecnologias Web I   Instalación Y Configuración Del Servidor A...
Sesion Nº 03 Tecnologias Web I Instalación Y Configuración Del Servidor A...
 
Manual de instalación drupal 7.2 mejorado Universidad de Los Andes
Manual de instalación drupal 7.2 mejorado Universidad de Los AndesManual de instalación drupal 7.2 mejorado Universidad de Los Andes
Manual de instalación drupal 7.2 mejorado Universidad de Los Andes
 
Instalación básica de php mybibli (pmb)
Instalación básica de php mybibli (pmb)Instalación básica de php mybibli (pmb)
Instalación básica de php mybibli (pmb)
 
Documentacion Final Proyecto UNIX
Documentacion Final Proyecto UNIXDocumentacion Final Proyecto UNIX
Documentacion Final Proyecto UNIX
 
05 Php. Configuracion De Php
05 Php. Configuracion De Php05 Php. Configuracion De Php
05 Php. Configuracion De Php
 

Destacado

Cl0301
Cl0301Cl0301
Cl0301lallet
 
La importancia de la web 2
La importancia de la web 2La importancia de la web 2
La importancia de la web 2edinson montoya
 
Calentamiento global
Calentamiento globalCalentamiento global
Calentamiento globalelidaescobar
 
Sistemas y tecnologia
Sistemas y tecnologiaSistemas y tecnologia
Sistemas y tecnologiaYury Otalora
 
Presentasjon poster
Presentasjon posterPresentasjon poster
Presentasjon posterDadio Robert
 
Clasificación de capacidades simplécticas en superficies sin frontera
Clasificación de capacidades simplécticas en superficies sin fronteraClasificación de capacidades simplécticas en superficies sin frontera
Clasificación de capacidades simplécticas en superficies sin fronteraJuliho Castillo
 
A Internet Revolucionando seus Negócios
A Internet Revolucionando seus NegóciosA Internet Revolucionando seus Negócios
A Internet Revolucionando seus NegóciosKenneth Corrêa
 
Tutorial Spider: Análise de Riscos
Tutorial Spider: Análise de RiscosTutorial Spider: Análise de Riscos
Tutorial Spider: Análise de RiscosPeter Mello
 
Qüestionari Badalona
Qüestionari BadalonaQüestionari Badalona
Qüestionari Badalonaguestb97fbd
 
Notas micro1 tsu
Notas micro1 tsuNotas micro1 tsu
Notas micro1 tsuLuis Zurita
 
PHMSA Regulation Application Certificate
PHMSA Regulation Application CertificatePHMSA Regulation Application Certificate
PHMSA Regulation Application CertificateHassan Badran
 
Projeto 5 Poapdf
Projeto 5 PoapdfProjeto 5 Poapdf
Projeto 5 Poapdfalptsoares
 
Gerenciamento de RH - Balanced Scorecard
Gerenciamento de RH - Balanced ScorecardGerenciamento de RH - Balanced Scorecard
Gerenciamento de RH - Balanced ScorecardKenneth Corrêa
 
BBM - Bolsa Brasileira de Mercadorias
BBM - Bolsa Brasileira de MercadoriasBBM - Bolsa Brasileira de Mercadorias
BBM - Bolsa Brasileira de MercadoriasKenneth Corrêa
 

Destacado (20)

Cl0301
Cl0301Cl0301
Cl0301
 
Hisem1 v4u15s
Hisem1 v4u15sHisem1 v4u15s
Hisem1 v4u15s
 
La importancia de la web 2
La importancia de la web 2La importancia de la web 2
La importancia de la web 2
 
El viaje
El viajeEl viaje
El viaje
 
Calentamiento global
Calentamiento globalCalentamiento global
Calentamiento global
 
Sistemas y tecnologia
Sistemas y tecnologiaSistemas y tecnologia
Sistemas y tecnologia
 
Presentasjon poster
Presentasjon posterPresentasjon poster
Presentasjon poster
 
Clasificación de capacidades simplécticas en superficies sin frontera
Clasificación de capacidades simplécticas en superficies sin fronteraClasificación de capacidades simplécticas en superficies sin frontera
Clasificación de capacidades simplécticas en superficies sin frontera
 
IMG_0006
IMG_0006IMG_0006
IMG_0006
 
Jokes
JokesJokes
Jokes
 
COMPRA DE ELP PELO BLOG
COMPRA DE ELP PELO BLOGCOMPRA DE ELP PELO BLOG
COMPRA DE ELP PELO BLOG
 
A Internet Revolucionando seus Negócios
A Internet Revolucionando seus NegóciosA Internet Revolucionando seus Negócios
A Internet Revolucionando seus Negócios
 
Tutorial Spider: Análise de Riscos
Tutorial Spider: Análise de RiscosTutorial Spider: Análise de Riscos
Tutorial Spider: Análise de Riscos
 
Qüestionari Badalona
Qüestionari BadalonaQüestionari Badalona
Qüestionari Badalona
 
Notas micro1 tsu
Notas micro1 tsuNotas micro1 tsu
Notas micro1 tsu
 
PHMSA Regulation Application Certificate
PHMSA Regulation Application CertificatePHMSA Regulation Application Certificate
PHMSA Regulation Application Certificate
 
Projeto 5 Poapdf
Projeto 5 PoapdfProjeto 5 Poapdf
Projeto 5 Poapdf
 
Gerenciamento de RH - Balanced Scorecard
Gerenciamento de RH - Balanced ScorecardGerenciamento de RH - Balanced Scorecard
Gerenciamento de RH - Balanced Scorecard
 
AMB Selfie Street, Sector 92, Gurgaon
AMB Selfie Street, Sector 92, GurgaonAMB Selfie Street, Sector 92, Gurgaon
AMB Selfie Street, Sector 92, Gurgaon
 
BBM - Bolsa Brasileira de Mercadorias
BBM - Bolsa Brasileira de MercadoriasBBM - Bolsa Brasileira de Mercadorias
BBM - Bolsa Brasileira de Mercadorias
 

Similar a Acceso a-base-de-datos-en-php

633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completo633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completoMETROPOLITANO
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completoErnesto Gamboa
 
633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completo633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completoUbeimar Navarro Herrera
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completoIgnacio Reyes
 
633f9e tutorial de php y my sql completo (1)
633f9e tutorial de php y my sql completo (1)633f9e tutorial de php y my sql completo (1)
633f9e tutorial de php y my sql completo (1)Eduardo Monroy Husillos
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completoAlberto Martinez
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completogenaro martinez
 
Documentacion Proyecto Final
Documentacion Proyecto FinalDocumentacion Proyecto Final
Documentacion Proyecto FinalMoisesAlvarez38
 
Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...
Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...
Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...Francisco Medina
 
07 Php. Instalando Php My Admin
07 Php. Instalando Php My Admin07 Php. Instalando Php My Admin
07 Php. Instalando Php My AdminJosé M. Padilla
 
Gestionar mis proyectos con ayuda de CodeIgniter
Gestionar mis proyectos con ayuda de CodeIgniterGestionar mis proyectos con ayuda de CodeIgniter
Gestionar mis proyectos con ayuda de CodeIgniterandrewzg
 
Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...
Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...
Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...Francisco Medina
 
Instalación y configuración de Moodle 2.7 en CentOS 7 con SELinux habilitado
Instalación y configuración de Moodle 2.7 en CentOS 7 con SELinux habilitadoInstalación y configuración de Moodle 2.7 en CentOS 7 con SELinux habilitado
Instalación y configuración de Moodle 2.7 en CentOS 7 con SELinux habilitadoFrancisco Medina
 

Similar a Acceso a-base-de-datos-en-php (20)

mysql y visual c++.pdf
mysql y visual c++.pdfmysql y visual c++.pdf
mysql y visual c++.pdf
 
Php andmysql
Php andmysqlPhp andmysql
Php andmysql
 
633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completo633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completo
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completo
 
633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completo633f9e tutorial de php y my sql completo
633f9e tutorial de php y my sql completo
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completo
 
633f9e tutorial de php y my sql completo (1)
633f9e tutorial de php y my sql completo (1)633f9e tutorial de php y my sql completo (1)
633f9e tutorial de php y my sql completo (1)
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completo
 
Php andmysql (1)
Php andmysql (1)Php andmysql (1)
Php andmysql (1)
 
Tutorial mysqlphp
Tutorial mysqlphpTutorial mysqlphp
Tutorial mysqlphp
 
Tutorial de php y my sql completo
Tutorial de php y my sql completoTutorial de php y my sql completo
Tutorial de php y my sql completo
 
Documentacion Proyecto Final
Documentacion Proyecto FinalDocumentacion Proyecto Final
Documentacion Proyecto Final
 
Phpmyadmin
PhpmyadminPhpmyadmin
Phpmyadmin
 
Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...
Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...
Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...
 
07 Php. Instalando Php My Admin
07 Php. Instalando Php My Admin07 Php. Instalando Php My Admin
07 Php. Instalando Php My Admin
 
Gestionar mis proyectos con ayuda de CodeIgniter
Gestionar mis proyectos con ayuda de CodeIgniterGestionar mis proyectos con ayuda de CodeIgniter
Gestionar mis proyectos con ayuda de CodeIgniter
 
Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...
Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...
Actividad Final: Instalación del LMS Moodle en CentOS con el módulo SELinux h...
 
Practica09
Practica09Practica09
Practica09
 
Openldap
OpenldapOpenldap
Openldap
 
Instalación y configuración de Moodle 2.7 en CentOS 7 con SELinux habilitado
Instalación y configuración de Moodle 2.7 en CentOS 7 con SELinux habilitadoInstalación y configuración de Moodle 2.7 en CentOS 7 con SELinux habilitado
Instalación y configuración de Moodle 2.7 en CentOS 7 con SELinux habilitado
 

Último

NARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARO
NARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARONARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARO
NARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFAROJosé Luis Palma
 
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptxLINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptxdanalikcruz2000
 
LA ECUACIÓN DEL NÚMERO PI EN LOS JUEGOS OLÍMPICOS DE PARÍS. Por JAVIER SOLIS ...
LA ECUACIÓN DEL NÚMERO PI EN LOS JUEGOS OLÍMPICOS DE PARÍS. Por JAVIER SOLIS ...LA ECUACIÓN DEL NÚMERO PI EN LOS JUEGOS OLÍMPICOS DE PARÍS. Por JAVIER SOLIS ...
LA ECUACIÓN DEL NÚMERO PI EN LOS JUEGOS OLÍMPICOS DE PARÍS. Por JAVIER SOLIS ...JAVIER SOLIS NOYOLA
 
plan-de-trabajo-colegiado en una institucion educativa
plan-de-trabajo-colegiado en una institucion educativaplan-de-trabajo-colegiado en una institucion educativa
plan-de-trabajo-colegiado en una institucion educativafiorelachuctaya2
 
Lecciones 04 Esc. Sabática. Defendamos la verdad
Lecciones 04 Esc. Sabática. Defendamos la verdadLecciones 04 Esc. Sabática. Defendamos la verdad
Lecciones 04 Esc. Sabática. Defendamos la verdadAlejandrino Halire Ccahuana
 
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptxPresentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptxYeseniaRivera50
 
Clasificaciones, modalidades y tendencias de investigación educativa.
Clasificaciones, modalidades y tendencias de investigación educativa.Clasificaciones, modalidades y tendencias de investigación educativa.
Clasificaciones, modalidades y tendencias de investigación educativa.José Luis Palma
 
EXPECTATIVAS vs PERSPECTIVA en la vida.
EXPECTATIVAS vs PERSPECTIVA  en la vida.EXPECTATIVAS vs PERSPECTIVA  en la vida.
EXPECTATIVAS vs PERSPECTIVA en la vida.DaluiMonasterio
 
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptxOLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptxjosetrinidadchavez
 
Día de la Madre Tierra-1.pdf día mundial
Día de la Madre Tierra-1.pdf día mundialDía de la Madre Tierra-1.pdf día mundial
Día de la Madre Tierra-1.pdf día mundialpatriciaines1993
 
Heinsohn Privacidad y Ciberseguridad para el sector educativo
Heinsohn Privacidad y Ciberseguridad para el sector educativoHeinsohn Privacidad y Ciberseguridad para el sector educativo
Heinsohn Privacidad y Ciberseguridad para el sector educativoFundación YOD YOD
 
Movimientos Precursores de La Independencia en Venezuela
Movimientos Precursores de La Independencia en VenezuelaMovimientos Precursores de La Independencia en Venezuela
Movimientos Precursores de La Independencia en Venezuelacocuyelquemao
 
RAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIA
RAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIARAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIA
RAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIACarlos Campaña Montenegro
 
Fundamentos y Principios de Psicopedagogía..pdf
Fundamentos y Principios de Psicopedagogía..pdfFundamentos y Principios de Psicopedagogía..pdf
Fundamentos y Principios de Psicopedagogía..pdfsamyarrocha1
 
Unidad II Doctrina de la Iglesia 1 parte
Unidad II Doctrina de la Iglesia 1 parteUnidad II Doctrina de la Iglesia 1 parte
Unidad II Doctrina de la Iglesia 1 parteJuan Hernandez
 
Factores ecosistemas: interacciones, energia y dinamica
Factores ecosistemas: interacciones, energia y dinamicaFactores ecosistemas: interacciones, energia y dinamica
Factores ecosistemas: interacciones, energia y dinamicaFlor Idalia Espinoza Ortega
 
BROCHURE EXCEL 2024 FII.pdfwrfertetwetewtewtwtwtwtwtwtwtewtewtewtwtwtwtwe
BROCHURE EXCEL 2024 FII.pdfwrfertetwetewtewtwtwtwtwtwtwtewtewtewtwtwtwtweBROCHURE EXCEL 2024 FII.pdfwrfertetwetewtewtwtwtwtwtwtwtewtewtewtwtwtwtwe
BROCHURE EXCEL 2024 FII.pdfwrfertetwetewtewtwtwtwtwtwtwtewtewtewtwtwtwtwealekzHuri
 

Último (20)

NARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARO
NARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARONARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARO
NARRACIONES SOBRE LA VIDA DEL GENERAL ELOY ALFARO
 
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptxLINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
LINEAMIENTOS INICIO DEL AÑO LECTIVO 2024-2025.pptx
 
Defendamos la verdad. La defensa es importante.
Defendamos la verdad. La defensa es importante.Defendamos la verdad. La defensa es importante.
Defendamos la verdad. La defensa es importante.
 
LA ECUACIÓN DEL NÚMERO PI EN LOS JUEGOS OLÍMPICOS DE PARÍS. Por JAVIER SOLIS ...
LA ECUACIÓN DEL NÚMERO PI EN LOS JUEGOS OLÍMPICOS DE PARÍS. Por JAVIER SOLIS ...LA ECUACIÓN DEL NÚMERO PI EN LOS JUEGOS OLÍMPICOS DE PARÍS. Por JAVIER SOLIS ...
LA ECUACIÓN DEL NÚMERO PI EN LOS JUEGOS OLÍMPICOS DE PARÍS. Por JAVIER SOLIS ...
 
Tema 7.- E-COMMERCE SISTEMAS DE INFORMACION.pdf
Tema 7.- E-COMMERCE SISTEMAS DE INFORMACION.pdfTema 7.- E-COMMERCE SISTEMAS DE INFORMACION.pdf
Tema 7.- E-COMMERCE SISTEMAS DE INFORMACION.pdf
 
plan-de-trabajo-colegiado en una institucion educativa
plan-de-trabajo-colegiado en una institucion educativaplan-de-trabajo-colegiado en una institucion educativa
plan-de-trabajo-colegiado en una institucion educativa
 
Lecciones 04 Esc. Sabática. Defendamos la verdad
Lecciones 04 Esc. Sabática. Defendamos la verdadLecciones 04 Esc. Sabática. Defendamos la verdad
Lecciones 04 Esc. Sabática. Defendamos la verdad
 
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptxPresentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
Presentación de Estrategias de Enseñanza-Aprendizaje Virtual.pptx
 
Clasificaciones, modalidades y tendencias de investigación educativa.
Clasificaciones, modalidades y tendencias de investigación educativa.Clasificaciones, modalidades y tendencias de investigación educativa.
Clasificaciones, modalidades y tendencias de investigación educativa.
 
EXPECTATIVAS vs PERSPECTIVA en la vida.
EXPECTATIVAS vs PERSPECTIVA  en la vida.EXPECTATIVAS vs PERSPECTIVA  en la vida.
EXPECTATIVAS vs PERSPECTIVA en la vida.
 
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptxOLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
OLIMPIADA DEL CONOCIMIENTO INFANTIL 2024.pptx
 
Día de la Madre Tierra-1.pdf día mundial
Día de la Madre Tierra-1.pdf día mundialDía de la Madre Tierra-1.pdf día mundial
Día de la Madre Tierra-1.pdf día mundial
 
Power Point: "Defendamos la verdad".pptx
Power Point: "Defendamos la verdad".pptxPower Point: "Defendamos la verdad".pptx
Power Point: "Defendamos la verdad".pptx
 
Heinsohn Privacidad y Ciberseguridad para el sector educativo
Heinsohn Privacidad y Ciberseguridad para el sector educativoHeinsohn Privacidad y Ciberseguridad para el sector educativo
Heinsohn Privacidad y Ciberseguridad para el sector educativo
 
Movimientos Precursores de La Independencia en Venezuela
Movimientos Precursores de La Independencia en VenezuelaMovimientos Precursores de La Independencia en Venezuela
Movimientos Precursores de La Independencia en Venezuela
 
RAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIA
RAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIARAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIA
RAIZ CUADRADA Y CUBICA PARA NIÑOS DE PRIMARIA
 
Fundamentos y Principios de Psicopedagogía..pdf
Fundamentos y Principios de Psicopedagogía..pdfFundamentos y Principios de Psicopedagogía..pdf
Fundamentos y Principios de Psicopedagogía..pdf
 
Unidad II Doctrina de la Iglesia 1 parte
Unidad II Doctrina de la Iglesia 1 parteUnidad II Doctrina de la Iglesia 1 parte
Unidad II Doctrina de la Iglesia 1 parte
 
Factores ecosistemas: interacciones, energia y dinamica
Factores ecosistemas: interacciones, energia y dinamicaFactores ecosistemas: interacciones, energia y dinamica
Factores ecosistemas: interacciones, energia y dinamica
 
BROCHURE EXCEL 2024 FII.pdfwrfertetwetewtewtwtwtwtwtwtwtewtewtewtwtwtwtwe
BROCHURE EXCEL 2024 FII.pdfwrfertetwetewtewtwtwtwtwtwtwtewtewtewtwtwtwtweBROCHURE EXCEL 2024 FII.pdfwrfertetwetewtewtwtwtwtwtwtwtewtewtewtwtwtwtwe
BROCHURE EXCEL 2024 FII.pdfwrfertetwetewtewtwtwtwtwtwtwtewtewtewtwtwtwtwe
 

Acceso a-base-de-datos-en-php

  • 1. Tema 8 PHP: Acceso a Bases de Datos Una de las razones por las que más se ha popularizado PHP, como ya comentamos en el tema anterior, es su posibilidad de conexión con casi todos los tipos de bases de datos. En este tema vamos a ver algunas nociones de MySQL: instalación y configuración rápida, organización, etc. La razón de ver MySQL es porque se trata de base de datos más usada con PHP, incluso se podría decir que es la base de datos “propia” de PHP, pues al parecer, PHP Group desarrolla en primera instancia para esta base de datos y después migra el trabajo a las librerías de acceso a otras bases de datos. Otra librería de acceso a bases de datos interesante es la de acceso a través de ODBC que nos abre el camino a la conexión a cualquier otro tipo de base de datos de la que no se tenga acceso “nativo” en PHP. También puede ser interesante usar el acceso ODBC para las bases de datos de las que se tiene funciones PHP directamente, pues, aunque aparentemente más complejo y aveces más limitado, el acceso ODBC nos garantiza cierta compatibilidad que prácticamente nos independiza del SGDB que se use. Así pues, en este tema vamos a trabajar sobre tres ejemplos de acceso a bases de datos MySQL y dos ejemplos ODBC en el que podremos trabajar tanto con MySQL como con otras bases de datos como MS-Access. 8.1. De vuelta con PHP Vamos en primera instancia a retomar algunos de los ejemplos PHP del tema anterior para ir calentando motores. En concreto, con idea de seguir con los ejemplos auto-ilustrativos del Tema 7, vamos a fusionar el ejemplo generico.php y ejemplos.php de forma que un solo código nos gestione una plantilla genérica y nos permita elegir y ejecutar los ejemplos de este tema, que a semejanza del caso anterior están en el directorio: "C:Archivos de programaApache GroupApachecgi-bintema8" La plantilla .phtml usada ahora se ha adaptado para este tema: Visualiza a la izquierda el código, a la derecha un formulario y encima de la tabla el posible resultado producido al invocar el formulario. La nueva plantilla se llama ahora: "C:Archivos de programaApache GroupApachehtdocstema8index.phtml" La idea es la de adaptar Apache para que también pueda tomar como página por defecto de un sitio Web ese nombre de fichero, cambiando en httpd.conf la siguiente línea: DirectoryIndex index.html … por esta otra: DirectoryIndex index.html index.phtml Recuerda arrancar Apache.
  • 2. Tema 8. PHP: Acceso a Bases de Datos 2 Listado 8.1. C:Archivos de programaApache GroupApachehtdocstema8index.phtml Plantilla de ejemplos del Tema 8. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <?php include "tema8/ejemplos.php"?> <HTML> <HEAD> <TITLE> <?php titulo()?> </TITLE> </HEAD> <BODY> <CENTER> <H1 style="font-weight:bold; font-size:200%; color:blue"> <?php titulo()?> </H1> <?php resultado()?> <TABLE width="100%" border="1" rules="all"> <TR align="center"> <TD> <B>C&oacute;digo</B><BR> </TD> <TD> <B>Formulario</B><BR> </TD> </TR> <TR valign="top"> <TD> <?php codigo()?> </TD> <TD> <?php formulario()?> </TD> </TR> </TABLE> </CENTER> </BODY> </HTML> El esquema es semejante al usado en el tema 7, pero hay que destacar que la función resultado ha sido sustituida por una formulario y una nueva función resultado debe reflejar en la parte superior el resultado de enviar el formulario. La función formulario invocará a una función del mismo nombre que el ejemplo que se esté visualizando, como antes hacia la función resultado. El código del nuevo ejemplo ejemplos.php queda así: Listado 8.2. C:Archivos de programaApache GroupApachecgi-bintema8ejemplos.php Programa que permite seleccinar uno de los ejemplos del Tema 8. <SCRIPT language="php"> if (!isset($Ejemplo)) $Ejemplo="Ejemplos"; $Fichero=strToLower("tema8/$Ejemplo.php"); @include_once($Fichero); if (!function_exists("titulo")) { function titulo() { global $Ejemplo; print($Ejemplo); } } if (!function_exists("resultado")) { function resultado() { } } function codigo() { global $Ejemplo; global $Fichero; if (@show_source($Fichero)) { function formulario() {
  • 3. Tema 8. PHP: Acceso a Bases de Datos 3 global $Ejemplo; $Ejemplo(); } } else print("¿$Ejemplo.php?"); } function ejemplos() { global $REQUEST_URI; include("tema8/plantillas/ejemplos.html"); } function opciones() { $Directorio=openDir(get_cfg_var("include_path")."/tema8/"); while ($Fichero=readDir($Directorio)) { $Fichero=ucFirst(strToLower($Fichero)); list($Ejem,$Ext)=explode(".",$Fichero); if ($Ejem AND !strCaseCmp($Ext,"php")) print("<OPTION>$Ejem</OPTION>n"); } closeDir($Directorio); } </SCRIPT> A destacar únicamente dos puntos. Lo primero que si la función resultado no existe (porque el ejemplo no hace nada cuando se envía el formulario), para que no se produzca error al invocarla, se crea vacía. Lo segundo, el formulario que debería estar en la función con el mismo nombre que el fichero (ejemplos() en este caso) no esta en este fichero, sino aparte, en un fichero con extensión .html, que aunque no es verdaderamente un fichero HTML, puede ser medianamente interpretado por un navegador o un programa de diseño HTML, de forma que se puede ver y cambiar independientemente del código, es decir se trata de una plantilla. Así pues, la función que muestra el formulario queda reducida a declarar como globales todas las variables que se usen en la plantilla .html e incluirla. Este esquema se repite en todos los ejemplos de este tema. El directorio que contiene las plantillas .html de los formularios es: "C:Archivos de programaApache GroupApachecgi-bintema8plantillas" Puedes ver el aspecto que tienen estas plantillas cargándolas desde tu disco local directamente (no a través del servidor Apache) con tu navegador. La plantilla que usamos en este “invocador” de ejemplos es: Listado 8.3. C:Archivos de … GroupApachecgi-bintema8plantillasejemplos.html Plantilla formulario para seleccionar ejemplos. </SCRIPT> <FORM action="<?=$REQUEST_URI?>" method="POST"> <CENTER> <LABEL> <B>Ejemplos:</B><BR> <SELECT name="Ejemplo"> <?php opciones()?> </SELECT> </LABEL><BR> <INPUT type="submit" value="Mostrar"> </CENTER> </FORM> <SCRIPT language="php"> Ahora puedes ver el resultado, invocar a cualquier ejemplo de este tema se hace con la URL: http://localhost/tema8
  • 4. Tema 8. PHP: Acceso a Bases de Datos 4 8.2. MySQL Monty Widenius quiso trabajar con APIs a bajo nivel de mSQL, comprobó que no eran suficientemente rápidas y decidió crear sus propias APIs MySQL. Así nació MySQL, una base de datos SQL (Structured Query Language) muy rapida, multi-hebra, multi-usuario y robusta según sus propios autores. Se trata, además, de un software gratuito licenciado bajo la General Public License de GNU. Instalación El primer paso que debemos dar es descargar la última versión desde http://www.mysql.com. Las distribuciones de binarios para Win32 siempre han sido “tradicionalmente” shareware. En el momento de editar estas páginas, se encuentra disponible una versión 3.23.28-gamma totalmente gratuita. El segundo paso es la descompresión del paquete y su instalación, ejecutando programa setup que aparece al descomprimir. La instalación compacta es suficiente para nuestro caso y para la mayoría de usuarios de MySQL que lo ejecuten sobre Win32. Si no le hemos indicado lo contrario el instalador nos habrá creado un directorio C:mysql, con varios ficheros y subdirectorios. Los importantes son estos tres subdirectorios: C:mysqldocs Contiene documentación sobre MySQL. Lo más interesante es el manual, accesible en HTML desde el fichero C:mysqldocsmanual_toc.html. C:mysqldata Por defecto almacena las bases de datos, en un subdirectorio cada una (con el mismo nombre que la base de datos). La distribución instala por defecto dos, la del sistema del propio servidor que se llama mysql y otra test, pero esta última está vacía. En subdirectorio correspondiente a la base de datos del sistema (mysql) se puede apreciar que MySQL guarda tres ficheros por cada tabla, con el mismo nombre que la tabla pero distintas extensiones: El formato se guarda en los ficheros .frm, los datos en los .myd y la información para gestionar el acceso por indices en los .myi. Las tablas de mysql son 5: user, host, db, tables_priv y columns_priv. C:mysqlbin Este directorio guarda los ejecutables: Demonios servidores, clientes, gestores y herramientas de test, administración y mantenimiento. Algunos de ellos son sólo para Windows NT o sólo para Windows 9x. El único que de momento nos interesa es winmysqladmin.exe, que lo ejecutaremos para comprobar la instalación y arrancar el servidor: WinMySQLadmin Cuando lo ejecutamos por primera vez nos pregunta por un usuario y clave para establecerlos como defecto. Esto lo hace por que detecta que no existe el fichero de configuración: C:windowsmy.ini En la documentación se explica como incluir distintas opciones en este fichero. Si le damos a cancelar y no introducimos ningún usuario y clave, creará un fichero my.ini con las opciones mínimas. No te tiene que preocupar no proporcionar usuario por defecto, pues la base de datos del sistema (la mysql que hemos visto en el directorio data) viene preparada inicialmente para
  • 5. Tema 8. PHP: Acceso a Bases de Datos 5 operar con cualquier usuario. Sin embargo el dar a cancelar también implica que no incluya un enlace directo a winmysqladmin.exe en el menú de inicio que producirá el arranque automático de este programa al iniciar una sesión en Windows. Puede ser interesante que copies o muevas ese enlace directo a otro menú, uno propio del MySQL, para poderlo invocar voluntariamente. Después, el programa WinMySQLadmin se quedará residente. Lo puedes apreciar por un semáforo con la luz verde que aparece a la derecha de la barra de tareas. Este semáforo tiene la luz verde cuando el servidor de MySQL se encuentra en marcha y rojo si está parado. El programa WinMySQLadmin no es el servidor, sino un programa que sirve para arrancar, parar y monitorizar al servidor. Éstas son las opciones que aparecen al solicitar el menú contextual sobre icono del semáforo, además de la opción de parar esta propia herramienta, que no implica parar el servidor MySQL. En conclusión, aunque esta herramienta nos permita curiosear el funcionamiento del servidor, principalmente servirá para poder arrancar y parar el servidor MySQL y comprobar mediante la luz del semáforo si está en marcha. Acceso a MySQL Otro programa llamado simplemente mysql (aparece también e el directorio C:mysqlbin) es el típico interprete SQL de línea de comandos. Invócalo para ver alguna tabla de la base de datos del sistema (la mysql): C:>C:mysqlbinmysql.exe mysql Ahora prueba a listar la tabla de usuarios y permisos: mysql> select * from user; Lo que estas viendo significa algo así como: • El usuario root tiene todos los privilegios posibles desde la máquina localhost. • Cualquier usuario desde cualquier máquina no tiene ningún privilegio. • Cualquier usuario desde localhost tiene todos los privilegios. • El usuario root desde cualquier máquina tiene todos los privilegios. • Es posible que aparezca otra fila con el usuario y clave que te pidió WinMySQLadmin. Acceso a MySQL mediante PHP Vamos a intentar visualizar la misma tabla de usuarios que hemos visto mediante el interprete SQL, pero a través de nuestro servidor Apache y un programa PHP. Para ello vamos a ver un ejemplo de visor de tablas: un formulario recoge máquina, usuario, base de datos y tabla, y mediante las funciones PHP de acceso a MySQL visualizamos la tabla. La plantilla del formulario será: Listado 8.4. C:Archivos de … GroupApachecgi-bintema8plantillasvisor.html Plantilla formulario para el visor. </SCRIPT> <FORM action="<?=$REQUEST_URI?>" method="POST"> <INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>"> <TABLE> <LABEL><TR> <TD><B>Host:</B></TD> <TD><INPUT type="text" name="Host" value="localhost"></TD> </TR></LABEL> <LABEL><TR>
  • 6. Tema 8. PHP: Acceso a Bases de Datos 6 <TD><B>Usuario:</B></TD> <TD><INPUT type="text" name="Usuario" value="root"></TD> </TR></LABEL> <LABEL><TR> <TD><B>Base de datos:</B></TD> <TD><INPUT type="text" name="BD"></TD> </TR></LABEL> <LABEL><TR> <TD><B>Tabla:</B></TD> <TD><INPUT type="text" name="Tabla"></TD> </TR></LABEL> <TR><TD colspan="2"><CENTER> <INPUT type="submit" name="Visualizar" value="Visualizar"> <INPUT type="submit" value="Limpiar"></CENTER> </TD></TR> </TABLE> </FORM> <SCRIPT language="php"> Lo primero que nuestro programa debe hacer es conectarse a un servidor MySQL en una máquina $Host como el usuario $Usuario, después seleccionar la base de datos $BD, lanzar la pregunta SQL que obtendrá la selección de las filas de la tabla $Tabla y por último interpretar el resultado: Listado 8.5. C:Archivos de programaApache GroupApachecgi-bintema8visor.php Visor de tablas MySQL. <SCRIPT language="php"> function visualizar($Host,$Usuario,$BD,$Tabla) { if (!mysql_connect($Host,$Usuario)) print("<P>Error al conectar con $Host como $Usuario</P>"); elseif (!mysql_select_db($BD)) print("<P>Error al seleccionar la base de datos $BD</P>"); elseif (!$Cursor=mysql_query("SELECT * FROM $Tabla")) print("<P>Error al obtener cursor a tabla $Tabla</P>"); else { print("<TABLE border="1" rules="all">n"); print("<TR>n"); for ($i=0;$i<mysql_num_fields($Cursor);$i++) print("<TH>".mysql_field_name($Cursor,$i)."</TH>n"); print("</TR>n"); while ($Fila=mysql_fetch_row($Cursor)) { print("<TR>n"); foreach ($Fila as $Campo) print("<TD>$Campo</TD>n"); print("</TR>n"); } print("</TABLE><BR>n"); } } function resultado() { global $Visualizar,$Host,$Usuario,$BD,$Tabla; if (isset($Visualizar)) { print("<P><B>Host:</B> $Host "); print("<B>Usuario:</B> $Usuario "); print("<B>Base de datos:</B> $BD "); print("<B>Tabla:</B> $Tabla</P>n"); visualizar($Host,$Usuario,$BD,$Tabla); } } function visor() { global $REQUEST_URI,$Ejemplo; include("tema8/plantillas/visor.html"); } </SCRIPT> La función mysql_connect(), de ser satisfactoria, devuelve un enlace a la base de datos. Este enlace debería ser pasado a las funciones mysql_select_db() y mysql_query(), pero ese parámetro es opcional, en caso de no hacerlo, se toma como enlace, la última conexión hecha, que en nuestro caso se trata de la única conexión hecha. La función mysql_query() devuelve un recurso, que puede ser interpretado en este caso como un cursor, del que poder extraer la información requerida en la pregunta. Son varias las
  • 7. Tema 8. PHP: Acceso a Bases de Datos 7 funciones que pueden extraer información de un recurso devuelto por mysql_query(), y distintas las formas o estrategias para interpretarlo: • Mediante la función mysql_fetch_object() se puede obtener un objeto por fila cuyos atributos son los campos de la tabla. • Mediante la función mysql_fetch_array() se pude obtener un array por fila cuyas claves sean los campos de la tabla, sus posiciones o ambas cosas. • mysql_fecth_row() es un caso particular del anterior, el array siempre esta indexado por posiciones (empezando por la 0). • Se puede acceder a cualquier fila y columna de la tabla mediante la función mysql_result(). Además es posible acceder a otra información sobre la respuesta, como el nombre los campos de la tabla o que cantidad de filas o columnas hay. En el ejemplo se usan las funciones myql_num_fields() y mysql_filed_name(). Esto nos permite poder visualizar los nombres de los campos en la cabecera de la tabla incluso cuando la tabla esta vacía: No pruebes solo la tabla user de la base de datos mysql, prueba también con una tabla vacía como tables_priv de la misma base de datos. 8.3. Manejo de bases de datos MySQL desde PHP Para poder ilustrar gran parte de las posibilidades de edición de las funciones PHP de acceso a MySQL, vamos a ver dos ejemplos más. El primero para poder crear una base nueva con la que experimentar (crear tablas, campos, modificarlos, borrar, etc.). El segundo, combinándolo con el manejo de sesiones nos permitirá editar (añadir, modificar y borrar) fila a fila en una base de datos. Gestor de base de datos (manejo de la estructura) En este ejemplo vamos a usar tres formularios distintos, dependiendo del nivel de atomicidad al que llevemos la gestión (base de datos, tabla o campo): Listado 8.6. C:Archivos de … GroupApachecgi-bintema8plantillasgesbd.html Plantilla formulario para el gestor en gestion a bases de datos. </SCRIPT> <FORM action="<?=$REQUEST_URI?>" method="POST"> <INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>"> <INPUT type="hidden" name="Gestion" value="<?=$Gestion?>"> <TABLE> <LABEL><TR> <TD><B>Host:</B></TD> <TD><INPUT type="text" name="Host" value="<?=$Host?>"></TD> </TR></LABEL> <LABEL><TR> <TD><B>Usuario:</B></TD> <TD><INPUT type="text" name="Usuario" value="<?=$Usuario?>"></TD> </TR></LABEL> <LABEL><TR> <TD><B>Base de datos:</B></TD> <TD><INPUT type="text" name="BD"></TD> </TR></LABEL> <TR><TD colspan="2"><CENTER> <INPUT type="submit" name="Operacion" value="Crear"> <INPUT type="submit" name="Operacion" value="Conectar"> <INPUT type="submit" name="Operacion" value="Eliminar"></CENTER> </TD></TR> </TABLE> </FORM> <SCRIPT language="php">
  • 8. Tema 8. PHP: Acceso a Bases de Datos 8 La variable $Gestion informará de que gestión se lleva a cabo (base de datos, tabla o columna), mientras $Operacion indica si se debe crear, eliminar, etc. Listado 8.7. C:Archivos de … GroupApachecgi-bintema8plantillasgestabla.html Plantilla formulario para el gestor en gestion a tablas. </SCRIPT> <FORM action="<?=$REQUEST_URI?>" method="POST"> <INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>"> <INPUT type="hidden" name="Gestion" value="<?=$Gestion?>"> <INPUT type="hidden" name="Host" value="<?=$Host?>"> <INPUT type="hidden" name="Usuario" value="<?=$Usuario?>"> <INPUT type="hidden" name="BD" value="<?=$BD?>"> <TABLE> <LABEL><TR> <TD><B>Tabla:</B></TD> <TD><CENTER><SELECT name="Tabla"> <?php tablas($BD)?> </SELECT></CENTER></TD> </TR></LABEL> <TR><TD colspan="2"><CENTER> <INPUT type="submit" name="Operacion" value="Cambiar"> <INPUT type="submit" name="Operacion" value="Eliminar"></CENTER> </TD></TR> <TR><TD colspan="2"><CENTER><B>o</B></CENTER></TD></TR> <LABEL><TR> <TD><B>Tabla:</B></TD> <TD><INPUT type="text" name="Nueva"></TD> </TR></LABEL> <TR><TD colspan="2"><CENTER> <INPUT type="submit" name="Operacion" value="Crear"></CENTER> </TD></TR> </TABLE> </FORM> <SCRIPT language="php"> Las variables del formulario anterior en este se mantienen ocultas. La variable $Nueva llevará el nombre de la tabla si se trata de una operación Crear. Listado 8.8. C:Archivos de … GroupApachecgi-bintema8plantillasgescampo.html Plantilla formulario para el gestor en gestion a campos. </SCRIPT> <FORM action="<?=$REQUEST_URI?>" method="POST"> <INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>"> <INPUT type="hidden" name="Gestion" value="<?=$Gestion?>"> <INPUT type="hidden" name="Host" value="<?=$Host?>"> <INPUT type="hidden" name="Usuario" value="<?=$Usuario?>"> <INPUT type="hidden" name="BD" value="<?=$BD?>"> <INPUT type="hidden" name="Tabla" value="<?=$Tabla?>"> <TABLE> <LABEL><TR> <TD><B>Campo:</B></TD> <TD><CENTER><SELECT name="Campo"> <?php campos($BD,$Tabla)?> </SELECT></CENTER></TD> </TR></LABEL> <TR><TD colspan="2"><CENTER> <INPUT type="submit" name="Operacion" value="Eliminar"></CENTER> </TD></TR> <TR><TD colspan="2"><CENTER><B>o</B></CENTER></TD></TR> <LABEL><TR> <TD><B>Campo:</B></TD> <TD><INPUT type="text" name="Nuevo"></TD> </TR></LABEL> <TR><TD> <LABEL><INPUT type="radio" name="Tipo" value="INT" checked>Entero</LABEL> </TD></TR> <TR><TD> <LABEL><INPUT type="radio" name="Tipo" value="VARCHAR">Cadena</LABEL> </TD><TD><CENTER>
  • 9. Tema 8. PHP: Acceso a Bases de Datos 9 <LABEL>Longitud: <INPUT type="text" name="Longitud" size="2"></LABEL> </CENTER></TD></TR> <TR><TD colspan="2"><CENTER> <INPUT type="submit" name="Operacion" value="Añadir"></CENTER> </TD></TR> </TABLE> </FORM> <SCRIPT language="php"> A la hora de añadir un campo, las variable $Nuevo y $Tipo aportan el nombre y el tipo respectivamente. Solo se permiten dos tipos de datos (para simplificar), el entero y la cadena. En este segundo tipo otra variable $Longitud aporta el número máximo de caracteres. También por simplificar, no se puede cambiar de tipo un campo, ha de eliminarse y añadirse de nuevo. Listado 8.9. C:Archivos de programaApache GroupApachecgi-bintema8gestor.php Gestor de bases de datos MySQL. <SCRIPT language="php"> function resultado() { global $Host,$Usuario,$BD,$Tabla,$Campo; global $Gestion,$Operacion; if (isset($Gestion)) { // Si se ha solicitado una gestion ... if (mysql_connect($Host,$Usuario)) { // se conecta y gestiona $Gestion=$Gestion($Operacion,$BD,$Tabla,$Campo); if ($Gestion!="gestionBD") { // Se muestran los datos print("<P><B>Host:</B> $Host "); print("<B>Usuario:</B> $Usuario "); print("<B>Base de datos:</B> $BD "); if ($Gestion!="gestionTabla") print("<B>Tabla:</B> $Tabla"); print("</P>n"); } } else { print("<P>Error al conectar con $Host como $Usuario</P>n"); $Gestion="gestionBD"; } } else { $Gestion="gestionBD"; $Host="localhost"; $Usuario="root"; } } function gestionBD($Operacion,$BD) { // Para base de datos switch ($Operacion) { case "Crear": // - o se crea: if (!mysql_create_db($BD)) { print("<P>Error al crear la base de datos $BD</P>n"); return("gestionBD"); } case "Conectar": // - o entra en la BD if (!mysql_select_db($BD)) { print("<P>Error al seleccionar la base de datos $BD</P>n"); return("gestionBD"); } return("gestionTabla"); case "Eliminar": // - o se elimina if (!mysql_drop_db($BD)) print("<P>Error al eliminar la base de datos $BD</P>n"); default: return("gestionBD"); } } function tablas($BD) { // Lista las tablas de una BD como opciones $Cursor=mysql_list_tables($BD); for ($i=0;$i<mysql_num_rows($Cursor);$i++) print("<OPTION>".mysql_tablename($Cursor,$i)."</OPTION>n"); } function gestionTabla($Operacion,$BD,&$Tabla) { // Para tabla global $Nueva; if (!mysql_select_db($BD)) { // Entra en la base de datos print("<P>Error al seleccionar la base de datos $BD</P>n");
  • 10. Tema 8. PHP: Acceso a Bases de Datos 10 return("gestionBD"); } if ($Operacion=="Eliminar") { // Elimina tabla o ... if (!mysql_query("DROP TABLE $Tabla")) print("<P>Error al eliminar la tabla $Tabla</P>"); return("gestionTabla"); } if ($Operacion=="Crear") { // ... crea tabla if (!mysql_query("CREATE TABLE $Nueva (id INT)")) { print("<P>Error al crear la tabla $Nueva</P>"); return("gestionTabla"); } $Tabla=$Nueva; } return("gestionCampo"); } function campos($BD,$Tabla) { // Lista los campos de una tabla $Cursor=mysql_list_fields($BD,$Tabla); for ($i=0;$i<mysql_num_fields($Cursor);$i++) print("<OPTION>".mysql_field_name($Cursor,$i)."</OPTION>n"); } function gestionCampo($Operacion,$BD,$Tabla,$Campo) { // Para campo global $Nuevo, $Tipo, $Longitud; if (!mysql_select_db($BD)) { // Entra en la base de datos print("<P>Error al seleccionar la base de datos $BD</P>n"); return("gestionBD"); } if ($Operacion=="Eliminar") // Elimina campo o ... if (!mysql_query("ALTER TABLE $Tabla DROP COLUMN $Campo")) print("<P>Error al eliminar el campo $Campo</P>"); if ($Operacion=="Añadir") { // ... añade campo if ($Tipo=="VARCHAR") $Tipo="$Tipo($Longitud)"; if (!mysql_query("ALTER TABLE $Tabla ADD COLUMN $Nuevo $Tipo")) print("<P>Error al añadir el campo $Nuevo tipo $Tipo</P>"); } return("gestionCampo"); } function gestor() { global $REQUEST_URI,$Ejemplo,$Gestion; global $Host,$Usuario,$BD,$Tabla; if ($Gestion=="gestionCampo") // Seleciona formulario include("tema8/plantillas/gescampo.html"); elseif ($Gestion=="gestionTabla") include("tema8/plantillas/gestabla.html"); else include("tema8/plantillas/gesbd.html"); } </SCRIPT> La variable $Gestion almacena el nombre de la función que debe realizar la gestión: gestionBD(), gestionTabla(), o gestionCampo(). Todas las gestiones son llamadas con el máximo de parámetros, aunque a algunas no les hace falta tantos. La función gestionBD() crea y destruye tablas con las funciones mysql_create_db() y mysql_drop_db() respectivamente. La función gestionTabla() destruye y crea tablas con las instrucciones DROP TABLE … y CREATE TABLE … de SQL. La función gestionCampo() elimina y añade campos con la instrucción ALTER TABLE … de SQL. Las funciones tablas() y campos() listan en los formularios, como opciones, las tablas de una base de datos y los campos de una tabla. Para ello utilizan funciones para extraer información sobre la estructura de la base de datos como mysql_list_tables() y mysql_list_fields().
  • 11. Tema 8. PHP: Acceso a Bases de Datos 11 Puedes probarlo creando nuevas bases de datos y/o eliminándolas después. Además puedes verificar los cambios que produces con el interprete de SQL (mysql) o con el visor del ejemplo anterior. Editor de base de datos (manejo de los datos) Vamos a ver otro ejemplo con el que poder rellenar de datos las bases de datos creadas con el anterior. La edición la haremos por fila, pudiendo pasar de una fila a otra para su edición. Esto supone establecer sesiones que nos guarden información sobre que fila de que tabla y base de datos estamos editando. El directorio de datos para las sesiones es, como en otros temas anteriores, el subdiretorio datos: C:Archivos de programaApache GroupApachecgi-bintema8datos La edición consistirá en modificar o borrar la fila actual o añadir una nueva al final, por esa razón, siempre se dejará editar una fila de más en blanco al final de la tabla. Las plantillas formulario para este ejemplo son dos, una para seleccionar una tabla y otra para editar una fila: Listado 8.10. C:Archivos de … GroupApachecgi-bintema8plantillaseditabla.html Plantilla formulario para el editor en selección de tabla. </SCRIPT> <FORM action="<?=$REQUEST_URI?>" method="POST"> <INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>"> <TABLE> <LABEL><TR> <TD><B>Host:</B></TD> <TD><INPUT type="text" name="Host" value="<?=$Host?>"></TD> </TR></LABEL> <LABEL><TR> <TD><B>Usuario:</B></TD> <TD><INPUT type="text" name="Usuario" value="<?=$Usuario?>"></TD> </TR></LABEL> <LABEL><TR> <TD><B>Base de datos:</B></TD> <TD><INPUT type="text" name="BD" value="<?=$BD?>"></TD> </TR></LABEL> <LABEL><TR> <TD><B>Tabla:</B></TD> <TD><INPUT type="text" name="Tabla" value="<?=$Tabla?>"></TD> </TR></LABEL> <TR><TD colspan="2"><CENTER> <INPUT type="submit" name="Operacion" value="Editar"></CENTER> </TD></TR> </TABLE> </FORM> <SCRIPT language="php"> Listado 8.11. C:Archivos de … GroupApachecgi-bintema8plantillasedifila.html Plantilla formulario para el editor en edición de fila. </SCRIPT> <FORM action="<?=$REQUEST_URI?>" method="POST"> <INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>"> <TABLE> <?php campos($Cursor,$Fila)?> <TR><TD colspan="2"><CENTER> <INPUT type="submit" name="Operacion" value="<?=boton('Añadir')?>"> <INPUT type="submit" name="Operacion" value="<?=boton('Modificar')?>"> <INPUT type="submit" name="Operacion" value="<?=boton('Borrar')?>"> </CENTER></TD></TR> <TR><TD colspan="2"><CENTER> <INPUT type="submit" name="Operacion" value="<?=boton('<<')?>"> <INPUT type="submit" name="Operacion" value="<?=boton('<')?>"> <INPUT type="submit" name="Operacion" value="Salir">
  • 12. Tema 8. PHP: Acceso a Bases de Datos 12 <INPUT type="submit" name="Operacion" value="<?=boton('>')?>"> <INPUT type="submit" name="Operacion" value="<?=boton('>>')?>"> </CENTER></TD></TR> </TABLE> </FORM> <SCRIPT language="php"> La función boton() determina si el botón queda habilitado o deshabilitado. Lamentablemente, esta funcionalidad de habilitar o deshabilitar controles no la reflejan correctamente todos los navegadores. El código es el siguiente: Listado 8.12. C:Archivos de programaApache GroupApachecgi-bintema8editor.php Editor de bases de datos MySQL. <SCRIPT language="php"> session_save_path("../../cgi-bin/tema8/datos"); // Antes que nada: session_start(); // Inicia o restablece sesion: if (!sizeof($HTTP_SESSION_VARS)) { // Si inicia, da valores $Host="localhost"; // iniciales a Host y $Usuario="root"; // Usuario y registra session_register("Host","Usuario"); // todas las variables a session_register("BD","Tabla","Fila"); // conservar en sesion } else // Si restablece, ... foreach ($HTTP_POST_VARS as $Variable => $Valor) if (session_is_registered($Variable)) // sobrescribe con los ${$Variable}=$Valor; // valores de formulario function resultado() { global $Operacion,$Host,$Usuario; global $BD,$Tabla,$Cursor; if (isset($Operacion) AND $Operacion!="Salir") if (!mysql_connect($Host,$Usuario)) print("<P>Error al conectar con $Host como $Usuario</P>n"); elseif (!mysql_select_db($BD)) print("<P>Error al seleccionar la base de datos $BD</P>"); elseif (!$Cursor=mysql_query("SELECT * FROM $Tabla")) print("<P>Error al obtener cursor a tabla $Tabla</P>"); else { print("<P><B>Host:</B> $Host "); // Informa de conexion, print("<B>Usuario:</B> $Usuario "); // base de datos y print("<B>Base de datos:</B> $BD "); // tabla con la que print("<B>Tabla:</B> $Tabla</P>n"); // operar return; } $Operacion="Salir"; } function campos($Cursor,$Fila) { // Muestra los campos de la fila $Tope=mysql_num_rows($Cursor); // corespondiente en formulario: print("<TR><TD colspan="2 "><CENTER>".($Fila+1)); print(" de ".$Tope."</CENTER></TD></TR>n"); for ($i=0;$i<mysql_num_fields($Cursor);$i++) { $Campo=mysql_field_name($Cursor,$i); print("<TR><TD><B>$Campo: </B></TD><TD><CENTER>"); print("<INPUT type="text" name="_${Campo}_""); if ($Fila<$Tope) print(" value="".mysql_result($Cursor,$Fila,$i)."""); print("></TD></CENTER></TD></TR>n"); } } function boton($Tipo) { // Determina que botones deben global $Cursor,$Fila; // o no estar deshabilitados. print("$Tipo"); switch ($Tipo) { case "Añadir"; if ($Fila==mysql_num_rows($Cursor)) return; break; case "<": case "<<": if ($Fila>0) return; break;
  • 13. Tema 8. PHP: Acceso a Bases de Datos 13 case "Modificar": case "Borrar": case ">": case ">>": if ($Fila<mysql_num_rows($Cursor)) return; } print("" disabled ""); } function operar($Operacion,&$Cursor,$Tabla,&$Fila) { switch ($Operacion) { // Determina, segun la operacion, case "Salir": // incrementar o decrementar la return(FALSE); // fila y hacer la operacion case "<": // corespondiente. if (--$Fila>=0) return(TRUE); case "Editar": case "<<": $Fila=0; return(TRUE); case ">": if (++$Fila<=mysql_num_rows($Cursor)) return(TRUE); case ">>": $Fila=mysql_num_rows($Cursor); return(TRUE); case "Modificar": case "Borrar": if ($Fila==mysql_num_rows($Cursor)) return(TRUE); } $Operacion($Cursor,$Tabla,$Fila); if (!$Cursor=mysql_query("SELECT * FROM $Tabla")) print("<P>Error al obtener cursor a tabla $Tabla</P>"); return(TRUE); } function añadir($Cursor,$Tabla,$Fila) { // Añade una fila global $HTTP_POST_VARS; for ($i=0;$i<mysql_num_fields($Cursor);$i++) { if ($i>0) $Valores.=","; $Campo=mysql_field_name($Cursor,$i); $Tipo=mysql_field_type($Cursor,$i); if (strToLower($Tipo)=="string") $Valores.="'"; $Valores.=$HTTP_POST_VARS["_${Campo}_"]; if (strToLower($Tipo)=="string") $Valores.="'"; } if (!mysql_query("INSERT INTO $Tabla VALUES($Valores)")) print("<P>Error añadiendo los valores:<BR>($Valores)</P>"); } function modificar($Cursor,$Tabla,$Fila) { // Cambia una fila global $HTTP_POST_VARS; for ($i=0;$i<mysql_num_fields($Cursor);$i++) { if ($i>0) { $Nuevos.=","; $Viejos.=" AND "; } $Campo=mysql_field_name($Cursor,$i); $Nuevos.="$Campo="; $Viejos.="$Campo="; $Tipo=mysql_field_type($Cursor,$i); if (strToLower($Tipo)=="string") { $Nuevos.="'"; $Viejos.="'"; } $Nuevos.=$HTTP_POST_VARS["_${Campo}_"]; $Viejos.=mysql_result($Cursor,$Fila,$i); if (strToLower($Tipo)=="string") { $Nuevos.="'"; $Viejos.="'"; } } if (!mysql_query("UPDATE $Tabla SET $Nuevos WHERE $Viejos")) print("<P>Error al sustituir por los valores:<BR>$Nuevos</P>"); } function Borrar($Cursor,$Tabla,$Fila) { // Elimina una fila for ($i=0;$i<mysql_num_fields($Cursor);$i++) { if ($i>0) $Valores.=" AND "; $Campo=mysql_field_name($Cursor,$i); $Valores.="$Campo=";
  • 14. Tema 8. PHP: Acceso a Bases de Datos 14 $Tipo=mysql_field_type($Cursor,$i); if (strToLower($Tipo)=="string") $Valores.="'"; $Valores.=mysql_result($Cursor,$Fila,$i); if (strToLower($Tipo)=="string") $Valores.="'"; } if (!mysql_query("DELETE FROM $Tabla WHERE $Valores")) print("<P>Error al borrar los valores:<BR>$Valores</P>"); } function editor() { global $REQUEST_URI,$Ejemplo; global $Operacion,$Host,$Usuario; // Opera y determina a global $Cursor,$BD,$Tabla,$Fila; // que formulario volver: if (operar($Operacion,$Cursor,$Tabla,$Fila)) include("tema8/plantillas/edifila.html"); else include("tema8/plantillas/editabla.html"); } </SCRIPT> Lo primero que hace el código es gestionar la sesión. Esta premura se justifica porque por defecto las sesiones se establecen por medio de cookies que deben ser introducidas como cabeceras de los mensajes de respuesta, así que, como vimos en el tema anterior, la gestión de una sesión debe realizarse antes de que el interprete PHP empiece a enviar el cuerpo del mensaje de respuesta. La función session_start() empieza una sesión si no existía, en caso contrario la reasume. Reasumirla significa restablecer los valores de las variables registradas en anteriores conexiones de esa misma sesión. Así pues, si no existe ninguna variable vinculada a la sesión ($HTTP_SESSION_VARS) significa que es la primera conexión de la sesión y que todavía no se ha registrado ninguna variable. En este caso registraremos todas las variables necesarias previa inicialización de las que nos interesen. Si no se trata de la primera conexión de la sesión, es posible que los valores de las variables registradas en la sesión (valores que tenían en la última conexión) entren en conflicto con los valores enviados por formulario (en nuestro caso por método POST). El problema es que valores asumen las variables globales PHP, el procedente de la sesión (el que perdura de la conexión anterior) o el que proviene del formulario. La directiva de configuración variables_order del fichero php.ini configura en que orden pasan los valores a las variables globales. Los valores de las variables globales predefinidas provienen de cinco posibles fuentes método GET, método POST, cookies, variables de entorno o sesión. En principio podríamos utilizar esta directiva para indicar que, en caso de conflicto, nos interesa más los valores introducidos por formulario (método POST) que los procedentes de la sesión. Esto significaría que PHP debería leer primero las variables registradas en la sesión y después las que vienen en la petición. Pero pensemos como obtiene PHP los valores de las variables de sesión: los obtiene de un fichero asociado al identificador de sesión donde guardó los valores al terminar la última conexión de la sesión. El identificador de sesión es un nombre único para cada sesión que el navegador y PHP se pasan mediante cookies y/o variables ocultas en formularios. Puedes comprobarlo al visualizar el código HTML desde tu navegador y buscando en el formulario de este ejemplo, por defecto la variable se llama PHPSESSID. PHP incluye por defecto esta variable en cualquier formulario que genere durante una sesión como alternativa a que el usuario desactive el sistema de cookies. En resumen, no se puede adelantar la valoración de las variables registradas en una sesión al paso de variables por cookies, método GET o método POST, pues se usa una variable pasada por alguno o algunos de estos tres métodos para identificar a la propia sesión. Así pues nos toca a nosotros mismos reescribir los valores de las variables globales que entren en conflicto por tener valor de procedencia sesión y procedencia formulario a la vez. Esto no es
  • 15. Tema 8. PHP: Acceso a Bases de Datos 15 complicado, pues tenemos los valores claramente identificados por procedencia en los arrays $HTTP_COOKIE_VARS, $HTTP_POST_VARS, $HTTP_GET_VARS y $HTTP_SESSION_VARS. La función campos() crea entradas del formulario con los campos de la fila en edición, si ésta es la última fila (la fila de más para añadir) las entradas quedan en blanco. Las variables asociadas a las entradas de texto tiene el mismo nombre que el campo de la tabla pero con un carácter _ al principio y al final, por si el nombre del campo coincide con alguna variable ya usada. La función operar() ajusta el nuevo valor para la fila y en los casos de Añadir, Modificar y Borrar, llama a la función del mismo nombre y luego vuelve a pedir el cursor para que refleje los cambios. Las funciones añadir(), modifica() y borrar() hacen uso de las instrucciones SQL INSER INTO …, UPDATE … y DELETE FROM …. Añadir() y modificar() utilizan el array $HTTP_POST_VARS para obtener los valores de los campos enviados por formulario de las variables _campo_ correspondientes. 8.4. ODBC Open Data Base Connection es un estándar que permite tratar de forma genérica las conexiones a bases de datos SQL. Cada fabricante de sistemas de bases de datos debe facilitar el controlador correspondiente para que a través de este se pueda conectar a sus bases de datos. Como cada sistema de base de datos crea, organiza y en general gestiona sus bases de datos de forma propia, ODBC solo proporciona funcionalidades genéricas a la mayoría de los sistemas, dejando fuera muchas operaciones “propias” para cada base de datos y al revés, pudiendo proporcionar funciones que no tienen efecto en algunos sistemas en concreto. A pesar de ello resulta muy útil e interesante, pues fusiona, por de alguna forma decirlo, todos los tipos de accesos a bases de datos en uno. Para ver todos los controladores instalados que dispones en tu máquina, ves al panel de control y abre el icono “ODBC” u “ODBC de 32 bits”, los controladores suelen llevar en su propio nombre una descripción de para qué sistema de base de datos están diseñados. Con ODBC, en vez de conectarse a una base de datos, hay que conectarse a una fuente de datos (Data Source). Estas fuentes de datos no son más que una descripción de cómo conectarse a una verdadera base de datos (con que controlador, a que base de datos, con que usuario, etc.). Estas descripciones aparecen en la misma ventana de los controladores ODBC como DSN (Data Source Name), y las hay de tres tipos, generales a sistema, propias del usuario o descritas en un fichero. Comprueba si ya tiene disponible alguna DSN a la que conectarte mediante ODBC. MySQL a través de ODBC MySQL también tiene sus controladores ODBC, puedes descargarlos de MySQL, en el momento de escribir este tema la última versión para Windows 9x es la 2.50.36. El instalador es en realidad un instalador de controladores ODBC genérico que Microsoft proporciona a los fabricantes de sistemas de bases de datos para que distribuyan sus controladores. Al descomprimir e instalar nos aparecerá la ventana de gestión de Data Sources por si queremos añadir una DSN. El instalador ya ha introducido como ejemplo una llamada sample-MySQL pero conecta con una base de datos test que posiblemente sigamos teniendo vacía, podemos modificar esta para crear la nuestra.
  • 16. Tema 8. PHP: Acceso a Bases de Datos 16 En cualquier caso (nueva o modificada), nosotros vamos a obtener una DSN con el nombre Tema8-ODBC-Mysql que conectará con el controlador ODBC de MySQL a una base de datos en localhost llamada Tema8 con el usuario root. Si no tienes una base de datos MySQL que se llame así (Tema8) créala con el ejemplo del gestor y rellénala con algún dato con el ejemplo editor, pues la vamos a usar en el siguiente ejemplo. Para comprobar el controlador ODBC de MySQL está correctamente instalado y que nuestra DSN está bien definida, llama al programa admndemo.exe que te habrá aparecido al descomprimir el instalador del controlador. Lo primero que te pide al arrancar es que le indiques con que DSN conectar. Selecciona nuestra DSN Tema8-ODBC-MySQL. Luego te aparecerá una ventana dividida en dos paneles. En el panel superior puedes escribir cualquier instrucción SQL (un SELECT será lo mas facil). En la barra de menús seleccionamos el menú Command seleccionamos la opción Execute y la instrucción SQL debe ejecutarse sobre nuestra base de datos Tema8. Visor ODBC Vamos a modificar el ejemplo visor para que en vez de conectar directamente con bases de datos MySQL lo haga a través de ODBC. Le llamaremos odbc precisamente. La nueva plantilla de formulario es: Listado 8.13. C:Archivos de … GroupApachecgi-bintema8plantillasodbc.html Plantila formulario para el visor ODBC. </SCRIPT> <FORM action="<?=$REQUEST_URI?>" method="POST"> <INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>"> <TABLE> <LABEL><TR> <TD><B>DSN ODBC:</B></TD> <TD><INPUT type="text" name="DSN" value="<?=$DSN?>"></TD> </TR></LABEL> <LABEL><TR> <TD><B>Usuario:</B></TD> <TD><INPUT type="text" name="Usuario" value="<?=$Usuario?>"></TD> </TR></LABEL> <LABEL><TR> <TD><B>Tabla:</B></TD> <TD><INPUT type="text" name="Tabla" value="<?=$Tabla?>"></TD> </TR></LABEL> <TR><TD colspan="2"><CENTER> <INPUT type="submit" name="Visualizar" value="Visualizar"> <INPUT type="submit" value="Limpiar"></CENTER> </TD></TR> </TABLE> </FORM> <SCRIPT language="php"> El código queda más sencillo todavía que el del visor: Listado 8.14. C:Archivos de programaApache GroupApachecgi-bintema8odbc.php Visor de tablas a través de ODBC. <SCRIPT language="php"> function titulo() { print("Visor ODBC"); } function visualizar($DSN,$Usuario,$Tabla) { print("<P>"); if ($DSN) print("<B>DSN ODBC:</B> $DSN "); if ($Usuario) print("<B>Usuario:</B> $Usuario ");
  • 17. Tema 8. PHP: Acceso a Bases de Datos 17 if ($Tabla) print("<B>Tabla:</B> $Tabla"); print("</P>n"); if (!$Conexion=odbc_connect($DSN,$Usuario,"")) print("<P>Error al conectar con $DSN como $Usuario</P>"); elseif (!$Cursor=odbc_exec($Conexion,"SELECT * FROM $Tabla")) print("<P>Error al obtener cursor a tabla $Tabla</P>"); else { odbc_result_all($Cursor,"border="1" rules="all""); print("<BR>n"); } } function resultado() { global $Visualizar,$DSN,$Usuario,$Tabla; if (isset($Visualizar)) visualizar($DSN,$Usuario,$Tabla); else $DSN=$Usuario=$Tabla=$Visualizar; } function odbc() { global $REQUEST_URI,$Ejemplo,$DSN,$Usuario,$Tabla; include("tema8/plantillas/odbc.html"); } </SCRIPT> La función odbc_connect() conecta con la DSN que se le indique. La función odbc_exec() ejecuta una instrucción SQL. Necesita forzosamente de la conexión devuelta por odbc_connect(). La función odbc_result_all() imprime el resultado de la consulta SQL en formato tabla HTML, la cadena que acompaña al cursor como parámetro proporciona los atributos para la etiqueta TABLE. Visualiza tablas de la base de datos Tema8 a través de la DSN Tema8-ODBC-MySQL mediante este ejemplo. Si dispones de MS-Access, prueba a crear una base de datos, créale una DSN (desde la ventana de controladores de ODBC que obtienes a través del panel de control se pueden añadir DSN nuevas) y visualiza sus tablas con este visor PHP de ODBC. Migración de unos a otros sistemas de bases de datos Como último ejemplo vamos a ver como pasar una tabla (estructura y datos) de una base de datos a otra, con independencia de sus sistemas de bases de datos mediante una DNS de origen y otra de destino. La plantilla a utilizar es: Listado 8.15. C:Archivos de … GroupApachecgi-bintema8plantillasmigrador.html Plantila formulario para el migrador. </SCRIPT> <FORM action="<?=$REQUEST_URI?>" method="POST"> <INPUT type="hidden" name="Ejemplo" value="<?=$Ejemplo?>"> <TABLE> <TR><TD colspan="2"> <CENTER>Migrar de ...</CENTER> </TD></TR> <LABEL><TR> <TD><B>DSN ODBC:</B></TD> <TD><INPUT type="text" name="De_DSN" value="<?=$De_DSN?>"></TD> </TR></LABEL> <LABEL><TR> <TD><B>Usuario:</B></TD> <TD><INPUT type="text" name="De_Usuario" value="<?=$De_Usuario?>"></TD> </TR></LABEL> <LABEL><TR>
  • 18. Tema 8. PHP: Acceso a Bases de Datos 18 <TR><TD colspan="2"> <CENTER>... a ...</CENTER> </TD></TR> <TD><B>DSN ODBC:</B></TD> <TD><INPUT type="text" name="A_DSN" value="<?=$A_DSN?>"></TD> </TR></LABEL> <LABEL><TR> <TD><B>Usuario:</B></TD> <TD><INPUT type="text" name="A_Usuario" value="<?=$A_Usuario?>"></TD> </TR></LABEL> <TR><TD colspan="2"> <CENTER>... la ...</CENTER> </TD></TR> <LABEL><TR> <TD><B>Tabla:</B></TD> <TD><INPUT type="text" name="Tabla" value="<?=$Tabla?>"></TD> </TR></LABEL> <TR><TD colspan="2"><CENTER> <INPUT type="submit" name="Migrar" value="Migrar"> <INPUT type="submit" value="Limpiar"></CENTER> </TD></TR> </TABLE> </FORM> <SCRIPT language="php"> Lo que el código de este ejemplo hace es: conectar con la DSN origen, obtener el cursor de la tabla origen, conectar con la DSN destino, extraer información de la estructura de la tabla origen y crear una tabla en destino como la origen, y por último copiar los datos obtenidos del cursor de la tabla origen a la tabla destino. Veamos, pues, el código: Listado 8.16. C:Archivos de programaApache GroupApachecgi-bintema8migrador.php Migrador de tablas a través de ODBC. <SCRIPT language="php"> function migrar($De_DSN,$De_Usuario,$A_DSN,$A_Usuario,$Tabla) { if (!$Origen=odbc_connect($De_DSN,$De_Usuario,"")) print("<P>Error al conectar con $De_DSN como $De_Usuario</P>"); elseif (!$Cursor=odbc_exec($Origen,"SELECT * FROM $Tabla")) print("<P>Error al obtener cursor a tabla $Tabla</P>"); elseif (!$Destino=odbc_connect($A_DSN,$A_Usuario,"")) print("<P>Error al conectar con $A_DSN como $A_Usuario</P>"); else { extraerDefinicionCampos($Cursor,$Definicion,$Formatos); if (odbc_exec($Destino,"CREATE TABLE $Tabla ($Definicion)")) copiaFilas($Cursor,$Formatos,$Destino,$Tabla); else print("<P>Error creando la tabla $Tabla con:<BR>($Definicion)</P>"); } } function extraerDefinicionCampos($Cursor,&$Definicion,&$Formatos) { for ($i=1;$i<=odbc_num_fields($Cursor);$i++) { if ($i>1) $Definicion.=","; $Definicion.=odbc_field_name($Cursor,$i); $Tipo=odbc_field_type($Cursor,$i); $Definicion.=" ".$Tipo; if (strToLower($Tipo)=="varchar") { $Definicion.="(".odbc_field_len($Cursor,$i).")"; $Formatos[]="'%s'"; } else $Formatos[]="%d"; } } function copiaFilas($Cursor,$Formatos,$Destino,$Tabla) { for ($i=1;$i<=odbc_num_rows($Cursor);$i++) { if (odbc_fetch_into($Cursor,$i,$Fila)) { foreach ($Fila as $j => $Campo) { if ($j==0) $Valores=sprintf($Formatos[$j],$Campo); else $Valores.=",".sprintf($Formatos[$j],$Campo); } if (!odbc_exec($Destino,"INSERT INTO $Tabla VALUES($Valores)")) print("<P>Error añadiendo los valores:<BR>($Valores)</P>");
  • 19. Tema 8. PHP: Acceso a Bases de Datos 19 } else print("<p>Error al leer fila $i</P>"); } } function resultado() { global $Migrar,$De_DSN,$De_Usuario,$A_DSN,$A_Usuario,$Tabla; if (isset($Migrar)) migrar($De_DSN,$De_Usuario,$A_DSN,$A_Usuario,$Tabla); else $De_DSN=$De_Usuario=$A_DSN=$A_Usuario=$Tabla=$Migrar; } function migrador() { global $REQUEST_URI,$Ejemplo,$Tabla; global $De_DSN,$De_Usuario,$A_DSN,$A_Usuario; include("tema8/plantillas/migrador.html"); } </SCRIPT> La función extraerDefinicionCampos() obtiene información de la estructura de la tabla (nombres y tipos de sus campos) a través de as funciones odbc_num_fields(), odbc_field_name(), odbc_field_type() y odbc_field_len() y la devuelve en la cadena $Definicion (usada para crear la tabla) y en el array $Formatos donde se guarda los formatos %d o ’%s’ según sea el campo entero o cadena (No estamos contemplando más tipos de datos en los ejemplos de este tema). La función copiaFilas() recorre todas las filas (odbc_num_rows()) mediante la función odbc_fetch_into() que pasa la fila a un array que es compuesto con los formatos correspondientes para enviar en una instrucción SQL INSER INTO …. Para probarlo créate una base de datos MS-Access vacía llamada Tema8. Si no dispones de MS-Access, en el directorio datos (donde se guarda la información de las sesiones) tienes una. Crea una DSN con el controlador ODBC de Access llamada Tema8-ODBC-Access para acceder a la base de datos vacía que has creado. Ahora ejecuta el ejemplo y pasa todas tus tablas de la base de datos Tema8 de MySQL a la nueva de Access a través de las DSN Tema8-ODBC-MySQL y Tema8-ODBC-Access. Abre la base de datos en Access y comprueba la migración. Si no dispones de Access usa el visor ODBC del ejemplo anterior. 8.5. Combinando ejemplos. Hemos terminado el tema habiendo creado una serie de herramientas que a través de Web nos van a permitir manipular datos en cualquier sistema de base de datos del que dispongamos su controlador ODBC, apoyándonos si es necesario en tablas que nos creemos o migremos a MySQL de forma temporal. Por ejemplo, si nos creamos la DSN Tema8-ODBC-Texto con el controlador ODBC de texto y vinculándolo a un directorio cualquiera (o creando uno vacío para tal menester), podemos hacar tablas en MySQL, pasarlas a texto a través del nuevo DSN y para consultarlas podemos usar el visor ODBC.