Está en la página 1de 145

Desarrollo Web con

PHP
Oscar Capuay Uceda

Contenido
DEDICATORIA

AGRADECIMIENTOS

INTRODUCCIN

I.

PREPARANDO LA PLATAFORMA DE DESARROLLO

11

INSTALACIN DEL SERVIDOR WEB Y PHP


INSTALACIN EN WINDOWS

11
11

II. DHTML

16

HTML
FORMATO DE TEXTO CON HTML
LISTAS
COMENTARIOS NO VISIBLES EN LA PANTALLA
CARACTERES ESPECIALES
ENLACES O HIPERVNCULOS
IMGENES
TABLAS
FORMULARIOS
HTML 4
JAVASCRIPT
ELEMENTOS BSICOS
COMENTARIOS
LITERALES
TIPOS DE DATOS
VARIABLES
OPERADORES
ESTRUCTURAS DE CONTROL
OBJETOS
OBJETOS PREDEFINIDOS
EVENTOS
DEFINICIN MEDIANTE CDIGO
MODELO DE OBJETOS DEL DOCUMENTO
OBJETO WINDOW
OBJETO DOCUMENT
OBJETO FORM
OTROS OBJETOS
FICHEROS .JS
HOJAS DE ESTILO EN CASCADA
SINTAXIS Y TIPOS BSICOS DE DATOS EN CSS2
PALABRAS CLAVE

16
19
19
22
23
25
28
31
38
45
61
62
62
63
64
64
65
68
70
71
75
77
78
79
82
83
88
90
91
95
97

III. INICIANDO LA PROGRAMACIN CON PHP

99

QUE ES PHP?
VARIABLES
CONSTANTES
TIPOS DE DATOS
EXPRESIONES
OPERADORES
OPERADORES DE ARITMTICA
OPERADORES DE ASIGNACIN
OPERADORES DE COMPARACIN
OPERADORES DE CONTROL DE ERRORES
OPERADORES DE EJECUCIN
OPERADORES DE INCREMENTO/DECREMENTO
OPERADORES DE LGICA
OPERADORES DE CADENA
OPERADORES DE MATRICES
OPERADORES DE TIPO

99
99
99
100
100
102
103
103
104
105
106
106
108
108
109
110

IV. ESTRUCTURAS DE CONTROL

113

SI (CONDICIONAL): IF
ELSE
ELSEIF
FOR
WHILE
DO..WHILE

113
114
114
115
115
115

V. ACCESO A DATOS CON PHP

117

FORMULARIOS HTML Y PHP


SUBIENDO ARCHIVOS AL SERVIDOR
ACCESO A BASES DE DATOS
CREANDO UNA BASE DE DATOS MYSQL EN MYSQL ADMINISTRATOR
CREANDO UNA BASE DE DATOS MYSQL EN PHPMYADMIN
ACCESO A MYSQL DESDE PHP
INSTALACIN DE POSTGRESQL SOBRE WINDOWS XP
CREANDO UNA BASE DE DATOS POSTGRESQL EN PGADMIN III
CREANDO UNA BASE DE DATOS POSTGRESQL EN PHPPGADMIN
ACCESO A POSTGRESQL DESDE PHP
ACCESO A MS SQL-SERVER DESDE PHP

124
129
132
132
137
143
151
158
165
170
177

VI. PHP ORIENTADO A OBJETOS

187

CLASES EN PHP
INSTANCIA DE UN OBJETO
EXTENDIENDO OBJETOS

187
187
188

AUTO CARGA DE OBJETOS


ACCESO A MYSQL CON PHP ORIENTADO A OBJETOS
MYSQLI
MYSQLI_STMT
MYSQLI_RESULT
PAGINANDO RESULTADOS
ARQUITECTURA MVC
MVC CON PHP
MVC Y PHP CON ACCESO A BASE DE DATOS
PDO PHP DATA OBJECT
CLASES PREDEFINIDAS
CONEXIONES CON PDO
EJECUCIN DE SENTENCIAS PREPARADAS CON PDO

189
191
191
193
194
202
205
205
212
215
215
218
221

VII. SEGURIDAD WEB

225

SEGURIDAD EN EL SISTEMA DE ARCHIVOS


SEGURIDAD EN BASE DE DATOS
INYECCIN SQL
SESIONES
AUTENTIFICACIN HTTP CON PHP
LOGIN
CAPTCHA

225
227
229
242
246
248
253

VIII. GENERACIN DE ARCHIVOS CON PHP

257

IMGENES
ARCHIVOS PDF
FPDF
ARCHIVOS XLS

257
264
264
274

IX. PHP + AJAX

281

AJAX
XAJAX
EVENTOS CON XAJAX
TRABAJO CON FORMULARIOS EN XAJAX
ERROR COMN
BSQUEDA EN BASE DE DATOS CON XAJAX
ADMINISTRACIN DE DATOS CON AJAX
CONTROLADOR CON AJAX
CAPA DE DATOS CON AJAX
VISTA CON AJAX

281
282
291
293
298
299
301
301
306
308

X. REFERENCIAS BIBLIOGRAFICAS

313

XI. ANEXOS

314

LISTA DE EJEMPLOS
LISTA DE TABLAS
LISTA DE FIGURAS

314
318
319

Acceso a Datos con PHP

V.

Acceso a Datos con PHP

Lo primero que tenemos que aprender es como insertar cdigo PHP en el


documento HTML.
En HTML se trabaja en base a marcas, las cuales tienen la siguiente forma
<ETIQUETA> </ETIQUETA>. Debido a esto, hay que indicar dentro del
conjunto de etiquetas que componen el documento Web el inicio y fin del
cdigo PHP insertado, para ello hay que utilizar los siguientes smbolos:
Para iniciar PHP: <?php
Para finalizar PHP: ?>
Ejemplo 55:

Pagina01.php

<HTML>
<HEAD>
<TITLE> Primer Ejemplo PHP </TITLE>
</HEAD>
<BODY>
El siguiente c&oacute;digo imprime Hipertext Preprocessor<BR>
<?php
echo "Hipertext Preprocessor";
?>
</BODY>
</HTML>
Cuando un cliente Web (navegador o browser) hace una solicitud a un
servidor Web, ste ubica el archivo solicitado y verifica si contiene cdigo
PHP o no, en caso que slo sea HTML, el archivo es enviado directamente
al cliente, pero en caso que tenga cdigo PHP es enviado a ser procesado el
documento que ha sido solicitado para ser procesado y luego enviar el
resultado del procesamiento al cliente. Segn el ejemplo anterior, el
documento sera enviado a ser procesado, en este proceso se interpretara
las lneas de cdigo y despus el resultado sera enviado al cliente.
A continuacin veremos el resultado de la solicitud y procesamiento de la
pgina programada anteriormente (pagina01.php).
Pagina01.php
<HTML>
<HEAD>
<TITLE> Primer Ejemplo PHP </TITLE>
</HEAD>
<BODY>
El siguiente c&oacute;digo imprime Hipertext Preprocessor<BR>
Hipertext Preprocessor
Oscar E Capuay Uceda

117

Acceso a Datos con PHP


</BODY>
</HTML>
Este cdigo resultante es interpretado en el navegador y se visualiza de la
siguiente como aparece en la figura 28.

Figura 54. Resultado de pagina01.php


Existen otras maneras de insertar cdigo PHP en el documento HTML, por
ejemplo:
1.- <? echo ("esta es la m&aacute;s simple, una instrucci&oacute;n de
procesado SGML \n"); ?>
<?= expression ?> Esto es una abreviatura de "<? echo expression ?>"
2.- <script language="php">
echo ("muchos editores (como FrontPage) no aceptan instrucciones de
procesado");
</script>
3.- <% echo ("Opcionalmente, puedes usar las etiquetas ASP"); %>
<%= $variable; # Esto es una abreviatura de "<% echo . . ." %>
El mtodo uno, no siempre est disponible. El formato corto de etiquetas
est disponible con la funcin short_tags() (slo PHP 3), activando el
parmetro del fichero de configuracin de PHP short_open_tag, o
compilando PHP con la opcin --enable-short-tags del comando configure.
Aunque est activa por defecto en php.ini-dist, no se aconseja el uso del
formato de etiquetas corto.
El mtodo tres slo est disponible si se han activado las etiquetas ASP en
el fichero de configuracin: asp_tags.
Nota: No se debe usar el formato corto de etiquetas cuando se desarrollen
aplicaciones o bibliotecas con intencin de redistribuirlas, o cuando se
desarrolle para servidores que no estn bajo nuestro control, porque puede
ser que el formato corto de etiquetas no est soportado en el servidor. Para
generar cdigo portable y redistribuble, asegrate de no usar el formato
corto de etiquetas.
Oscar E Capuay Uceda

118

Acceso a Datos con PHP


La etiqueta de fin de bloque incluir tras ella la siguiente lnea si hay alguna
presente. Adems, la etiqueta de fin de bloque lleva implcito el punto y
coma; no necesitas por lo tanto aadir el punto y coma final de la ltima lnea
del bloque PHP.
En el desarrollo de software son muy importantes los comentarios en los
scripts, en el caso de PHP, los comentarios tienen la siguiente sintaxis:
Cuando es un comentario de una lnea se usa: //
Cunado un comentarios es de varias lneas, se delimita el
comentario utilizando: /* y */
Ejemplo 56:

Comentarios

<?php
// Este es un ejemplo de una lnea
/*
Este es otro ejemplo,
pero tiene
varias lneas
comentadas
*/
?>
Ejemplo 57:

Sentencia if (1)

pagina02.php
<HTML>
<HEAD>
<TITLE> Ejemplo de la sentencia if </TITLE>
</HEAD>
<BODY>
El siguiente c&oacute;digo utiliza la sentencia if de php<BR>
<?php
$nota=12;
if($nota>=10.5)
echo
"<em>Felicitaciones<em>,
Ud.
obtuvo
el
calificativo
de
<strong>$nota</strong> (APROBADO)";
else
echo
"Ud.
obtuvo
el
calificativo
de
<strong>$nota</strong>
(DESAPROBADO)";
?>
</BODY>
</HTML>
Ejemplo 58:

Sentencia if (2)

pagina03.php
<HTML>
Oscar E Capuay Uceda

119

Acceso a Datos con PHP


<HEAD>
<TITLE> Ejemplo de la sentencia if </TITLE>
</HEAD>
<BODY>
El siguiente c&oacute;digo utiliza la sentencia if de php<BR>
<?php
$nota=12;
if($nota>=10.5)
{
echo
"<em>Felicitaciones<em>,
Ud.
obtuvo
el
calificativo
de
<strong>".$nota."</strong> (APROBADO)";
}
else
{
echo "Ud. obtuvo el calificativo de <strong>".$nota."</strong>
(DESAPROBADO)";
}
?>
</BODY>
</HTML>
Ejemplo 59:

Sentencia if (3)

pagina04.php
<HTML>
<HEAD>
<TITLE> Ejemplo de la sentencia if </TITLE>
</HEAD>
<BODY>
El siguiente c&oacute;digo utiliza la sentencia if de php<BR>
<?php
$nota=12;
if($nota>=10.5)
{ ?>
<em>Felicitaciones<em>, Ud. obtuvo el calificativo de <strong><?php echo
$nota ?></strong> (APROBADO)
<?php }
else
{ ?>
Ud. obtuvo el calificativo de <strong><?php echo $nota ?></strong>
(DESAPROBADO)
<?php }
?>
</BODY>
</HTML>
Todos los ejemplos de la sentencia if generan la siguiente salida Web.

Oscar E Capuay Uceda

120

Acceso a Datos con PHP

Figura 55. Resultado de pagina04.php


Ahora veamos el uso de la sentencia for para la generacin de tablas html.
En este primer ejemplo generamos una tabla con una columna y n filas.
Ejemplo 60:

Sentencia for (1)

Pagina05.php
<HTML>
<HEAD>
<TITLE> Ejemplo de la sentencia for </TITLE>
</HEAD>
<BODY>
Uso de la sentencia for de php<BR>
<?php
$filas=15;
echo "<table border=\"1\">"; //iniciamos la tabla
for($i=1;$i<=$filas;$i++) //creamos varias filas con el for
{
echo "<tr><td>$i</td><tr>"; // escribir fila con el valor de: i
}
echo "</table>"; //cerramos la tabla
?>
</BODY>
</HTML>
Resultado Web

Oscar E Capuay Uceda

121

Acceso a Datos con PHP

Figura 56. Resultado de pagina05.php


Ejemplo 61:

Sentencia for (2)

pagina06.php
<HTML>
<HEAD><TITLE> Ejemplo de la sentencia for </TITLE></HEAD>
<BODY> Uso de la sentencia for de php<BR>
<?php
$filas=15; $columnas=5;
echo "<table border=\"1\">"; //iniciamos la tabla
for($i=1;$i<=$filas;$i++) //creamos varias filas con el for
{
echo "<tr>"; // crear fila
for($j=1;$j<=$columnas;$j++)
{
echo "<td>$i $j</td>"; //escribir columnas (celdas)
}
echo "<tr>"; // terminar la fila
}
echo "</table>"; //cerramos la tabla
?>
</BODY>
</HTML>
Oscar E Capuay Uceda

122

Acceso a Datos con PHP


Resultado Web

Figura 57. Resultado de pagina06.php


Ejemplo 62:

Sentencia for (3)

Con el siguiente cdigo obtenemos la tabla del ejemplo anterior.


pagina07.php
<HTML>
<HEAD><TITLE> Ejemplo de la sentencia for </TITLE></HEAD>
<BODY> Uso de la sentencia for de php<BR>
<?php
$filas=15; $columnas=5;
?>
<table border="1">
<?php
for($i=1;$i<=$filas;$i++) //creamos varias filas con el for
{ ?>
<tr>
<?php for($j=1;$j<=$columnas;$j++)
{ ?>
<td><?php echo "$i $j" ?></td>
<?php } ?>
<tr>
<?php } ?>
</table>
</BODY>
Oscar E Capuay Uceda

123

Acceso a Datos con PHP


</HTML>
La mayor parte de aplicaciones Web suelen trabajar con PHP utilizando
variables y objetos ingresados por los usuarios a travs de formularios
HTML.

Formularios HTML y PHP


Veamos un ejemplo sencillo en el que se envan datos a una pgina PHP
utilizando los mtodos POST y GET, respectivamente.
Ejemplo 63:

Envo de datos de un formulario a una pgina PHP

formulario01.html
<html>
<head>
<title>Formulario</title>
</head>
<body>
<form name="form1" method="post" action="pagina08.php">
Ingresa tu nombre
<input name="txtnombre" type="text" id="txtnombre">
<input type="submit" name="Submit" value="Enviar">
</form>
</body>
</html>
En la etiqueta form, en su propiedad action, especificamos el destino de los
datos, es decir, la pgina PHP que recibir los datos del formulario. En este
caso pagina08.php, y no olvidemos que en el mtodo estamos especificando
POST.
Adems debemos tomar en cuenta el nombre del objeto (caja de texto
input tipo text) txtnombre, pues ser en nombre que usaremos en la pgina
de destino.
pagina08.php
<HTML>
<HEAD><TITLE> Ejemplo de envio de datos</TITLE></HEAD>
<BODY>
Tu nombre es:
<?php
echo $_POST[txtnombre];
?>
</table>
</BODY>
</HTML>
En esta pgina podemos ver que usamos el array $_POST de PHP para
acceder a los datos enviados a travs de este mtodo. Tambien podemos
Oscar E Capuay Uceda

124

Acceso a Datos con PHP


observar que en la barra de direccin no aparece ninguna variable,
solamente el nombre de la pgina PHP.
Resultado Web

Figura 58. Resultado de formulario01.html

Figura 59. Resultado de pagina08.php


Ahora veamos como sera este ejemplo utilizando el mtodo GET.
Formulario02.html
<html>
<head>
<title>Formulario</title>
</head>
<body>
<form name="form1" method="get" action="pagina09.php">
Ingresa tu nombre
<input name="txtnombre" type="text" id="txtnombre">
<input type="submit" name="Submit" value="Enviar">
</form>
</body>
</html>
pagina09.php
<HTML>
<HEAD><TITLE> Ejemplo de envio de datos</TITLE></HEAD>
<BODY>
Tu nombre es:
<?php

Oscar E Capuay Uceda

125

Acceso a Datos con PHP


echo $_GET[txtnombre];
?>
</table>
</BODY>
</HTML>
Resultado Web:

Figura 60. Resultado de formulario02.html

Figura 61. Resultado de pagina09.php

Figura 62. URL incluyendo datos enviados


En la figura 36 podemos ver en la barra de direccin los datos enviados a
travs del mtodo GET, por lo que debemos utilizar el array $_GET de PHP
para acceder a ellos.

Ahora utilizaremos algunos objetos adicionales en el formulario, tipo INPUT:


checkbox, radio, y hidden.
formulario03.html
<html>
<head>
Oscar E Capuay Uceda

126

Acceso a Datos con PHP


<title>Formulario</title>
</head>
<body>
<form name="form1" method="post" action="pagina10.php">
<input type="hidden" name="oculto" value="XYZ">
<table width="90%" border="0">
<tr>
<td>Temas de inter&eacute;s:
<input name="tema[]" type="checkbox" id="tema[]" value="red">Redes
de computadoras
<input name="tema[]" type="checkbox" id="tema[]" value="web">World
Wide Web
<input
name="tema[]"
type="checkbox"
id="tema[]"
value="seguridad">Seguridad Inform&aacute;tica</td>
</tr>
<tr>
<td>Sexo:
<input name="sexo" type="radio" value="M">
Masculino
<input name="sexo" type="radio" value="F">
Femenino</td>
</tr>
<tr>
<th><input type="submit" name="Submit" value="Enviar"></th>
</tr>
</table>
</form>
</body>
</html>
En esta pgina encontramos tres objetos checkbox que tienen el mismo
nombre y que sern enviados como array de datos al archivo pagina10.php,
pero cada uno de ellos tiene un valor distinto para poder diferenciarlos.
Cuando estos objetos lleguen a su destino solo podremos leer los valores de
aquellos objetos que fueron chequeados.
En el caso de los botones de opcin pasa algo similar pero esta tcnica
siempre la utilizo pues nos sirve para agrupar radio-botones (botones de
opcin).
Resultado Web:

Figura 63. Resultado de formulario03.html

Oscar E Capuay Uceda

127

Acceso a Datos con PHP

Al presionar el botn Enviar enviamos los datos del formulario al archivo:


pagina10.php que se detalla a continuacin:
pagina10.php
<HTML>
<HEAD><TITLE> Ejemplo de envio de datos</TITLE></HEAD>
<BODY>
El valor del objeto oculto es: <?php echo $_POST[oculto]?><br>
El sexo seleccionado: <?php echo $_POST[sexo]?><br>
Los temas seleccionados son:<br>
<?php
if(count($_POST[tema])>0) {
foreach($_POST[tema] as $k => $v) {
echo "- ".$v."<br>";
}
}
else {
echo "(No hay temas seleccionados)";
}
?>
</table>
</BODY>
</HTML>
En este script podemos encontrar la funcin count, esta funcin permite
determinar la cantidad de elementos que tiene un array de datos, en este
caso, el array $_POST[tema].
Tambin encontramos la sentencia foreach que sirve para recorrer un array
de datos, extrayendo sus elementos: ndice y valor, que en el script estn
representados por $k y $v respectivamente.
El resultado del procesamiento del archivo pagina10.php es:

Figura 64. Resultado de pagina10.php


Segundo caso: aqu observamos que no hay tema seleccionado.

Oscar E Capuay Uceda

128

Acceso a Datos con PHP

Figura 65. Resultado de formulario03.html (segundo caso)

Figura 66. Resultado de pagina10.php (segundo caso)

Subiendo archivos al servidor


En muchas aplicaciones Web es necesario enviar o subir archivos al servidor
Web, es por ello que veremos a continuacin el procedimiento que nos
permita realizar esta tarea sin ningn problema.

Figura 67. Resultado de formulario04.html


Ejemplo 64:

Subir un archivo al servidor Web

formulario04.html
<html>
<head>
Oscar E Capuay Uceda

129

Acceso a Datos con PHP


<title>Subir archivos</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<form action="pagina11.php" method="post" enctype="multipart/form-data"
name="form1">
Seleccione un archivo
<input type="file" name="archivo" size="50">
<input type="submit" name="Submit" value="Enviar">
</form>
</body>
</html>

Figura 68. Seleccin de un archivo en un formulario


Es muy importante indicar en el formulario la propiedad enctype para el
envo de datos, tal y como lo apreciamos en el cdigo anterior
(formulario04.html): enctype="multipart/form-data".
En este formulario seleccionamos el archivo que deseamos subir y luego
presionamos el botn Enviar.
pagina11.php
<?php
//leyendo los datos del archivo recibido
$nombre_real=$_FILES[archivo][name];
$tamano=$_FILES[archivo][size];
$tipo=$_FILES[archivo][type];
//este es el nombre que tiene el archivo cuando llega al server
$nombre_temporal=$_FILES[archivo][tmp_name];
//imprimimos los datos
echo "Archivo: " . $nombre_real . " - Tipo:" . $tipo . " Tama&ntilde;o:" .
$tamano . " - Temporal:" . $nombre_temporal . "<br>";
//movemos el archivo al directorio destino.
$carpeta="archivos";
$destino=$carpeta."\\".$nombre_real;
if(move_uploaded_file ($nombre_temporal,$destino)) echo "archivo subido
exitosamente";
else echo "El archivo no logr&oacute; subir al servidor";
?>
En el script podemos ver que debemos recibir los datos del archivo a travs
del array $_FILES[], indicando el nombre del objeto HTML que insertamos en
Oscar E Capuay Uceda

130

Acceso a Datos con PHP


el formulario y luego en la siguiente dimensin del array especificamos el
dato que queremos leer.
La funcin move_uploaded_file, realiza un chequeo para asegurar que el
archivo $nombre_temporal sea un archivo cargado vlido (lo que quiere decir
que fue cargado a travs del mecanismo de carga HTTP POST de PHP). Si
el archivo es vlido, ser movido al nombre de archivo dado por $destino. Si
$nombre_temporal no es un archivo cargado vlido, entonces no se tomar
ninguna accin, y move_uploaded_file() devolver FALSE, de lo contrario
devolver TRUE.

Figura 69. Datos de un archivo enviado al servidor

Oscar E Capuay Uceda

131

Acceso a Datos con PHP

Acceso a Bases de Datos


Para aprender a acceder a una base de datos tomaremos como manejador
de base de datos a MySQL.

Creando una base de datos MySQL en MySQL Administrator


Crearemos paso a paso la base de datos dbdemo y una tabla llamada
persona.
Primero abrimos MySQL Administrator e ingresamos los datos solicitados.

Figura 70. Conexin al servidor MySQL con MySQL Administrador

Figura 71. Inicio de MySQL Administrator


Oscar E Capuay Uceda

132

Acceso a Datos con PHP


Luego hacemos clic con el botn derecho del Mouse sobre una de las bases
de datos para crear una nueva seleccionando Create New Schema.

Figura 72.

Men de MySQL Administrator

Demos escribir el nombre de la nueva base de datos y presionar OK.

Figura 73. Creando una base de datos


Una vez que presionamos OK tenemos creada la base de datos.

Oscar E Capuay Uceda

133

Acceso a Datos con PHP

Figura 74. Base de datos creada en MySQL Administrator


Ahora creamos la tabla persona, para ello hacemos click en el botn Create
Table.

Figura 75. Creando una tabla

Oscar E Capuay Uceda

134

Acceso a Datos con PHP


Escribimos el nombre de la tabla: persona

Figura 76. Ingreso del nombre de la tabla


Luego, agregamos el primer campo: idpersona haciendo doble click en la
primera celda de la seccin Columns and Indices

Figura 77. Definicin de campos de la tabla


Podemos notar que por defecto se establece al campo como clave primaria,
tipo entero y autoincrementable.
Luego de ingresar todos los datos de los campos de la tabla tenemos:

Figura 78. Estructura de la tabla


Luego presionamos el botn Apply changes.

Oscar E Capuay Uceda

135

Acceso a Datos con PHP

Figura 79. Confirmacin para la creacin de la tabla


Confirmamos el resultado y presionamos Execute para terminar.

Figura 80. Lista de elementos incluyendo la tabla recientemente creada

Oscar E Capuay Uceda

136

Acceso a Datos con PHP

Creando una base de datos MySQL en phpmyadmin


El primer paso es crear una base de datos utilizando PHPMyADMIN una
aplicacin Web que nos permite administrar nuestras bases de datos MySQL
desde la plataforma Web.
En nuestro navegador escribiremos la siguiente direccin:
http://localhost/phpmyadmin/
La palabra localhost de la direccin anterior se refiere al nombre con el
que se ha configurado a nuestro servidor APACHE que hemos instalado con
WAMP, es decir, hacemos referencia al servidor Web que esta instalado en
nuestra mquina, por lo que no necesitamos de una conexin a Internet para
desarrollar todos los ejemplos que veremos a continuacin.

Figura 81. Interfaz de phpMyAdmin


Vemos la pgina de inicio de phpmyadmin con la lista de bases de datos que
ha encontrado en el servidor. En caso que recin este utilizando MySQL slo
ver las bases de datos que vienen por defecto con la instalacin.
En el lado derecho de la pgina tenemos una caja de texto que nos permite
escribir el nombre de una nueva base de datos.

Oscar E Capuay Uceda

137

Acceso a Datos con PHP

Figura 82. Interfaz para cear una nueva base de datos


Escribimos el nombre de la base de datos y luego elegimos el cotejamiento o
conjunto de caracteres que se utilizar para guardar los datos en la base.

Figura 83. Creando la base de datos dbdemo.


Una vez creada la base de datos podemos crear las tablas que necesitemos,
en nuestro caso crearemos la tabla persona, la cual estar compuesta por
cinco campos.

Oscar E Capuay Uceda

138

Acceso a Datos con PHP

Figura 84. Creando la tabla persona.

Al presionar el botn Continuar aparecer la siguiente pgina:

Figura 85. Especificacin de los campos de la tabla


En esta pgina debemos especificar los atributos de cada campo. Por
ejemplo el campo idpersona ser la clave primaria y adems ser
autoincrementable.

Figura 86. Autoincremento en el campo idpersona.


A continuacin se detalla la estructura de la tabla persona:
Idpersona int(11) autoincrement PK
nombres varchar(50)
apellidos varchar(50)
email varchar(100)
telefono varchar(15)
Una vez ingresados estos datos presionamos el botn Grabar.

Oscar E Capuay Uceda

139

Acceso a Datos con PHP

Figura 87. Estructura de la tabla creada


Una vez creada la tabla aparecer en la lista ubicada en el lado izquierdo de
la pgina.
Ahora agregaremos registros a la tabla:

Figura 88. Men de operaciones que se pueden realizar sobre las


tablas de la base de datos.
En la parte superior de la pgina encontramos varios enlaces.
Seleccionamos Insertar.

Oscar E Capuay Uceda

140

Acceso a Datos con PHP

Figura 89. Formularios para la insercin de registros


Esta interfaz nos permite ingresar nuevos registros a la tabla.
En nuestro caso no hay necesidad de ingresar el valor para idpersona
debido a que es un campo autoincrementable. Luego presionamos el botn
Continuar.

Figura 90. Datos para los nuevos registros

Oscar E Capuay Uceda

141

Acceso a Datos con PHP

Figura 91. Operacin realizada con xito y el script SQL que ha sido
ejecutado.
Siempre phpmyadmin nos mostrar el script SQL que acabamos de ejecutar,
en este caso la orden de insercin en la tabla persona.
Luego podemos ver la lista de registros haciendo click en Examinar.

Figura 92. Listado de registros de la tabla persona

Oscar E Capuay Uceda

142

Acceso a Datos con PHP

Acceso a MySQL desde PHP


En esta seccin primero veremos las funciones que nos permitirn
conectarnos a un servidor de base de datos y luego elegir la base. Luego
desarrollaremos las acciones bsicas sobre una tabla como: insercin,
edicin, eliminacin y bsqueda.
Ejemplo 65:

Conexin a MySQL

pagina12.php
<?php
$conex=mysql_connect("localhost","root","") or die(mysql_error());
mysql_select_db("dbdemo",$conex) or die(mysql_error());
?>
La funcin mysql_connect abre una conexin a un servidor MySQL, y
necesita para ello tres parmetros: el nombre o direccin del servidor de
base de datos, un nombre de usuario y su contrasea. Podemos observar
luego de la funcin mysql_connect que aparece el operador OR el cual nos
permite ejecutar la orden die() en caso que la conexin fallara. La orden die()
imprime un mensaje y termina el script actual, en este caso el mensaje ser
el resultado de la ejecucin de la funcin mysql_error() retorna el texto del
error de la ltima funcin MySQL o '' (cadena vaca) si no ocurri error.
Una vez hecha la conexin almacenamos en la variable $conex el
identificador de enlace de dicha conexin. Esta variable la utilizaremos para
seleccionar la base de datos a la cual accederemos mediante la funcin
mysql_select_db() que tiene como primer parmetro el nombre de la base de
datos.
Ahora veremos una pgina que incluye el script escrito en pagina12.php para
realizar la conexin y luego hacer una consulta de todos los registros de la
tabla persona.
Ejemplo 66:

Listado de registros

pagina13.php
<?php
include "pagina12.php"; //incluimos la conexion
$sql="select * from persona"; //consulta sql
$rspersona=mysql_query($sql) or die(mysql_error());//ejecucion de la
sentencia sql
while($reg=mysql_fetch_array($rspersona)) {
echo $reg[idpersona]." - ".$reg[nombres]." ".$reg[apellidos]."<br>";
}
?>
Podemos ver en el script que con la funcin mysql_query podemos ejecutar
una sentencia SQL la cual almacena el resultado en la variable $rspersona.
Oscar E Capuay Uceda

143

Acceso a Datos con PHP


Una vez hecho esto leemos los registros con la funcin mysql_fetch_array()
la cual devuelve una matriz que corresponde a la sentencia extrada, o falso
si no quedan ms filas. La funcin mysql_fetch_array() es una versin
extendida de mysql_fetch_row(). Adems de guardar los datos en el ndice
numrico de la matriz, guarda tambin los datos en los ndices asociativos,
usando el nombre de campo como clave. De esta forma leemos cada uno de
los registros hasta llegar al final del conjunto de registros obtenidos en la
consulta. Podemos deducir que cada vez que esta funcin es ejecutada, el
puntero interno se desplaza al siguiente registro.
Resultado Web

Figura 93. Resultado de pagina13.php


Ejemplo 67:

Listado de registros en una tabla

Ahora le daremos una mejor presentacin al listado.


pagina14.php
<?php
include "pagina12.php"; //incluimos la conexion
//consulta sql
$sql="select * from persona";
//ejecucion de la sentencia sql
$rspersona=mysql_query($sql) or die(mysql_error());
?>
<table>
<tr>
<th>Id</th>
<th>Nombres</th>
<th>Apellidos</th>
<th>Editar</th>
<th>Eliminar</th>
</tr>
<?php
//mostrar los registros
while($registro=mysql_fetch_array($rspersona))
Oscar E Capuay Uceda

144

Acceso a Datos con PHP


{ ?>
<tr>
<td><?php echo "$registro[idpersona]"?></td>
<td><?php echo "$registro[nombres]"?></td>
<td><?php echo "$registro[apellidos]"?></td>
<td><a href="pagina16.php?idpersona=<?php echo
"$registro[idpersona]"?>">editar</a></td>
<td><a href="pagina18.php?idpersona=<?php echo
"$registro[idpersona]"?>">eliminar</a></td>
</tr>
<?php
}
?>
</table>
<br>
<a href="formulario05.html">Agregar Registro</a>
Resultado Web

Figura 94. Resultado de pagina14.php


Ahora pasaremos a programar el formulario y la pgina PHP para la
insercin de registros.

Ejemplo 68:

Insercin de registros en una tabla

Formulario05.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Nuevo registro</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="pagina15.php">
Oscar E Capuay Uceda

145

Acceso a Datos con PHP


<table width="80%" border="0" align="center">
<tr>
<th colspan="2">Nuevo Registro</th>
</tr>
<tr>
<td>Nombres</td>
<td><input name="nombres" type="text" id="nombres" size="50"
maxlength="50" /></td>
</tr>
<tr>
<td>Apellidos</td>
<td><input name="apellidos" type="text" id="apellidos" size="50"
maxlength="50" /></td>
</tr>
<tr>
<td>E-Mail</td>
<td><input
name="email"
type="text"
id="email"
size="50"
maxlength="100" /></td>
</tr>
<tr>
<td>Tel&eacute;fono</td>
<td><input
name="telefono"
type="password"
id="telefono"
maxlength="15" /></td> </tr>
<tr>
<th colspan="2"><input name="Submit" type="submit" class="boton"
value="Guardar" />
<input name="Submit2" type="button" class="boton" value="Cancelar"
onclick="location='pagina14.php'" /></th>
</tr>
</table>
</form>
</body>
</html>
Como resultado del cgio HTML obtenemos este formulario, el cual enviar
los datos a pagina15.php.

Figura 95. Formulario05.html

Oscar E Capuay Uceda

146

Acceso a Datos con PHP


Pagina15.php
<?php
include "pagina12.php";
//sentencia para insertar el usuario
$sql="insert into persona
values('','$_POST[nombres]','$_POST[apellidos]','$_POST[email]','$_POST[t
elefono]')";
//ejecutar sentencia
mysql_query($sql) or die(mysql_error());
echo "La persona fue registrada exitosamente<br>";
echo "<a href='pagina14.php'>Listado de Personas</a>";
?>
Resultado Web:

Figura 96. Resultado de pagina15.php


Ejemplo 69:

Edicin de registros

Pagina16.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php
include "pagina12.php";
$sql="select * from persona where idpersona='$_GET[idpersona]'";
$rs=mysql_query($sql) or die(mysql_error());
//ejecutar sentencia
if(mysql_num_rows($rs)>0)

Oscar E Capuay Uceda

147

Acceso a Datos con PHP


$registro=mysql_fetch_array($rs);
?>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Nuevo registro</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="pagina17.php">
<table width="80%" border="0" align="center">
<tr> <th colspan="2">Edici&oacute;n de Persona</th> </tr>
<tr>
<td>Nombres</td> <td><input name="nombres" type="text" id="nombres"
size="50" maxlength="50" value="<?php echo $registro[nombres]?>" /></td>
</tr>
<tr>
<td>Apellidos</td> <td><input name="apellidos" type="text"
id="apellidos" size="50" maxlength="50" value="<?php echo
$registro[apellidos]?>" /></td>
</tr>
<tr>
<td>E-Mail</td> <td><input name="email" type="text" id="email"
size="50" maxlength="100" value="<?php echo $registro[email]?>"/></td>
</tr>
<tr>
<td>Tel&eacute;fono</td> <td><input name="telefono" type="text"
id="telefono" maxlength="15" value="<?php echo
$registro[telefono]?>"/></td>
</tr>
<tr>
<th colspan="2"><input name="Submit" type="submit" class="boton"
value="Guardar" /> <input name="Submit2" type="button" class="boton"
value="Cancelar" onclick="location='pagina14.php'" /></th>
</tr>
</table>
</form>
</body>
</html>
Resultado Web:

Oscar E Capuay Uceda

148

Acceso a Datos con PHP

Figura 97. Formulario de edicin de un registro

pagina17.php
<?php
include "pagina12.php";
//sentencia para editar el registro
$sql="update persona set nombres='$_POST[nombres]',
apellidos='$_POST[apellidos]', email='$_POST[email]',
telefono='$_POST[telefono]' where idpersona='$_POST[idpersona]'";
//ejecutar sentencia
mysql_query($sql) or die(mysql_error());
echo "La persona fue actualizada exitosamente<br>";
echo "<a href='pagina14.php'>Listado de Personas</a>";
?>
Resultado Web:

Figura 98. Resultado de pagina17.php


Ejemplo 70:

Eliminacin de registros

pagina18.php
<?php
include "pagina12.php";
//sentencia para eliminar el registro
$sql="delete from persona where idpersona='$_GET[idpersona]'";
Oscar E Capuay Uceda

149

Acceso a Datos con PHP


//ejecutar sentencia
mysql_query($sql) or die(mysql_error());
echo "La persona fue eliminada exitosamente<br>";
echo "<a href='pagina14.php'>Listado de Personas</a>";
?>
En la siguiente seccin veremos el acceso a una base de datos PostgreSQL.

Oscar E Capuay Uceda

150

Acceso a Datos con PHP

Instalacin de PostgreSQL sobre Windows XP


Para instalar PostgreSQL debemos descargar el instalador de la seccin
Download de http://www.postgresql.org.
Una vez descargado el archivo zip, lo descomprimimos y tendremos los
siguientes archivos:

Figura 99. Archivos de instalacin de PostgreSQL


Ejecutamos el archivo postgresql-8.3

Figura 100. Asistente de instalacin de PostgreSQL


Seleccionamos el idioma que se usar en la instalacin (English) y
presionamos Start.

Oscar E Capuay Uceda

151

Acceso a Datos con PHP

Figura 101. Inicio del asistente de instalacin


Se recomienda cerrar los programas abiertos y y luego leemos las
instrucciones necesarias para empezar.

Figura 102. Notas de instalacin

Oscar E Capuay Uceda

152

Acceso a Datos con PHP

Figura 103. Opciones de instalacin


Seleccionamos las herramientas e interfaces que deseamos instalar.

Figura 104. onfiguracin del servicio


Luego ingresamos el password para la cuenta postgres.

Oscar E Capuay Uceda

153

Acceso a Datos con PHP

Figura 105. Error en la cuenta


Si el usuario postgres no existe aparecer el mensaje anterior para preguntar
si deseamos crearlo responderemos Si.

Figura 106. Password aleatorio


Si no ingresamos un password lo suficientemente seguro nos aparecer este
mensaje para asignarnos un password aleatorio. Si deseamos conservar
nuestro password ingresado anteriormente presionaremos No.

Figura 107. Cuenta del superusuario


Ingresamos otro password para el super-usuario del sistema de base de
datos (por razones de seguridad, se recomienda no utilizar el password
anterior).

Oscar E Capuay Uceda

154

Acceso a Datos con PHP

Figura 108. Habilitar lenguaje procedural


Seleccionamos el lenguaje procedural y presionamos Next para luego
seleccionar los mdulos adicionales que podemos instalar.

Figura 109. El asistente est listo para iniciar la instalacin


Ahora ya esta todo listo para la instalacin.

Oscar E Capuay Uceda

155

Acceso a Datos con PHP

Figura 110. Instalando PostgreSQL

Figura 111. Instalacin completa


Finalmente nos aparecer esta ventana que nos indica el final de la
instalacin. Si no queremos correr el Stack Builder quitamos el check y
presionamos Finish.
Una vez instalado vamos al men Inicio Programas y seleccionamos el
men de PostgreSQL. En este men abrimos PgAdmin III.
Oscar E Capuay Uceda

156

Acceso a Datos con PHP

Figura 112. pgAdmin III


Si hacemos doble click sobre el servidor PostgreSQL Database Server 8.3
aparecer la siguiente ventana para logearnos.

Figura 113. Conexin al servidor desde pgAdmin III

Oscar E Capuay Uceda

157

Acceso a Datos con PHP

Creando una base de datos PostgreSQL en pgAdmin III


Al ingresar a pgAdmin ya podemos administrar nuestras bases de datos.

Figura 114. Listado de elementos del servidor


Creamos una base de datos.

Figura 115. Creando una base de datos


Ingresamos los datos de la nueva base de datos (dbdemo).

Oscar E Capuay Uceda

158

Acceso a Datos con PHP

Figura 116. Datos de la nueva base de datos


Luego creamos la tabla persona, haciendo click con el botn derecho del
mouse y seleccionando New table

Figura 117. Creando una nueva tabla

Oscar E Capuay Uceda

159

Acceso a Datos con PHP

Figura 118. Propiedades de la tabla


Especificamos los datos de la tabla y luego los campos. Cuando el tipo de
dato es autoincrementable seleccionamos el tipo serial.

Figura 119. Propiedades de una nueva columna

Oscar E Capuay Uceda

160

Acceso a Datos con PHP

Figura 120. Columna nombres de la tabla persona


Luego especificamos la clave primaria de la clave

Figura 121. Clave primaria de la tabla persona


Luego de especificar el nombre del constraint seleccionamos los campos de
la clave primaria.

Oscar E Capuay Uceda

161

Acceso a Datos con PHP

Figura 122. Columnas pertenecientes a la clave primaria


Finalmente registramos el constraint y luego podemos ver el script de la
tabla.

Figura 123. Script SQL generado para la creacin de la tabla

Oscar E Capuay Uceda

162

Acceso a Datos con PHP

Figura 124. Final de la creacin de la tabla


Haciendo click derecho sobre la tabla persona seleccionamos View Data
para ver los registros.

Figura 125. Men desplegable de la tabla

Oscar E Capuay Uceda

163

Acceso a Datos con PHP

Figura 126. Vista de datos de la tabla


Hacemos doble click sobre la primera fila e ingresamos luego los datos.

Figura 127. Editando datos en la tabla


Ahora veremos la creacin de la base de datos con otra herramienta.

Oscar E Capuay Uceda

164

Acceso a Datos con PHP

Creando una base de datos PostgreSQL en phpPgAdmin


El primer paso es crear una base de datos utilizando phpPgAdmin una
aplicacin Web que nos permite administrar nuestras bases de datos
Postgres.
Escribiremos la siguiente direccin: http://localhost/phppgadmin/

Figura 128. Interfaz de phpPgAdmin


Ingresamos el usuario y password para tener acceso a las bases de datos.

Figura 129. Logeo de usuarios al servidor PostgreSQL


Una vez ingresados los datos presionamos el botn Autenticar para
ingresar.

Oscar E Capuay Uceda

165

Acceso a Datos con PHP

Figura 130. Interfaz de ingreso a phpPgAdmin


Ahora crearemos una base de datos PostgreSQL, haciendo clic en el
hipervnculo: Crear base de datos.

Figura 131. Creando una nueva base de datos


Ahora nuestra base de datos dbdemo aparece en el margen izquierdo de la
aplicacin Web.

Oscar E Capuay Uceda

166

Acceso a Datos con PHP

Figura 132. Base de datos dbdemo creada


Seleccionamos la base de datos para crear la tabla persona.

Figura 133. Men de elementos de la base de datos

Figura 134. creando la tabla persona


Ingresamos el nombre de la tabla y especificamos la cantidad de campos
que vamos a crear y luego presionamos Prximo.

Oscar E Capuay Uceda

167

Acceso a Datos con PHP

Figura 135. Ingresando los campos de la tabla


Al igual que en MySQL seleccionamos autoincrement para la clave primaria
de la tabla (el valor del campo se auto-incrementa en cada nuevo registro
insertado), en este caso indicaremos lo mismo a travs de SERIAL.

Figura 136. Autoincremento para la clave primaria

Figura 137. Estructura de la tabla


Haciendo clic en el hipervnculo Insertar, agregaremos registros a la tabla.

Oscar E Capuay Uceda

168

Acceso a Datos con PHP

Figura 138. Formulario de ingreso de nuevos registros

Figura 139. Listado de registros


Para conectarnos a PostgreSQL desde PHP debemos aseguarrnos que las
libreras de PHP para PostgreSQL estn disponibles, para ello vamos a
men de WAMP y listamos las extensiones de PHP.

Oscar E Capuay Uceda

169

Acceso a Datos con PHP

Figura 140. Activando la extensin php_pgsql


Una vez verificado procedemos a programar la pgina de conexin:

Acceso a PostgreSQL desde PHP


Ejemplo 71:

Conexin a PostgreSQL

pagina22.php
<?php
//conexion al servidor PostgreSQL
$conex=pg_connect("host=localhost dbname=dbdemo port=5432 user=oscar
password=123456") or die("Error en la conexin");
?>

pagina23.php
<?php
include "pagina22.php"; //incluimos la conexion
//consulta sql
$sql="select * from persona";
//ejecucion de la sentencia sql
$rspersona=pg_query($sql) or die(pg_last_error($conex));
while($reg=pg_fetch_array($rspersona)) {
echo $reg[idpersona]." - ".$reg[nombres]." ".$reg[apellidos]."<br>";
}
?>
La funcin pg_last_error() muestra el ltimo error ocurrido en la conexin
activa, la cual es el parmetro.

Oscar E Capuay Uceda

170

Acceso a Datos con PHP


Resultado Web:

Figura 141. Resultado de pagina23.php


Ejemplo 72:

Listado de registros en una tabla HTML.

pagina24.php
<?php
include "pagina22.php"; //incluimos la conexion
//consulta sql
$sql="select * from persona";
//ejecucion de la sentencia sql
$rspersona=pg_query($sql) or die(pg_last_error($conex));
?>
<table>
<tr>
<th>Id</th>
<th>Nombres</th>
<th>Apellidos</th>
<th>Editar</th>
<th>Eliminar</th>
</tr>
<?php
//mostrar los registros
while($registro=pg_fetch_array($rspersona))
{ ?>
<tr>
<td><?php echo "$registro[idpersona]"?></td>
<td><?php echo "$registro[nombres]"?></td>
<td><?php echo "$registro[apellidos]"?></td>
<td><a href="pagina26.php?idpersona=<?php echo
"$registro[idpersona]"?>">editar</a></td>
<td><a href="pagina28.php?idpersona=<?php echo
"$registro[idpersona]"?>">eliminar</a></td>
</tr>
<?php
}
//Liberar conjunto de resultados
pg_free_result($rspersona);
Oscar E Capuay Uceda

171

Acceso a Datos con PHP


// Cerrar conexion
pg_close($conex);
?>
</table>
<br>
<a href="formulario06.html">Agregar Registro</a>
</body>
</html>
Resultado Web:

Figura 142. Resultado de pagina24.php


Ejemplo 73:

Insercin de registro en PostgreSQL.

formulario06.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Nuevo registro</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="pagina25.php">
<table width="80%" border="0" align="center">
<tr> <th colspan="2">Nuevo Registro</th> </tr>
<tr>
<td>Nombres</td> <td><input name="nombres" type="text"
id="nombres" size="50" maxlength="50" /></td>
</tr>
<tr>
<td>Apellidos</td> <td><input name="apellidos" type="text"
id="apellidos" size="50" maxlength="50" /></td>
</tr>
<tr>

Oscar E Capuay Uceda

172

Acceso a Datos con PHP


<td>E-Mail</td> <td><input name="email" type="text" id="email"
size="50" maxlength="100" /></td>
</tr>
<tr>
<td>Tel&eacute;fono</td> <td><input name="telefono" type="text"
id="telefono" maxlength="15" /></td>
</tr>
<tr>
<th colspan="2"><input name="Submit" type="submit" class="boton"
value="Guardar" /> <input name="Submit2" type="button" class="boton"
value="Cancelar" onclick="location='pagina14.php'" /></th>
</tr>
</table>
</form>
</body>
</html>
El destino de los datos de este formulario es: pagina25.php.
Resultado Web:

Figura 143. Resultado de formulario06.html


pagina25.php
<?php
include "pagina22.php";
//sentencia para insertar el usuario
$sql="insert into persona (nombres, apellidos, email, telefono ) values
('$_POST[nombres]','$_POST[apellidos]','$_POST[email]','$_POST[telefono]'
)";
//ejecutar sentencia
pg_query($sql) or die(pg_last_error($conex));
echo "La persona fue registrada exitosamente<br>";
echo "<a href='pagina24.php'>Listado de Personas</a>";
?>
Oscar E Capuay Uceda

173

Acceso a Datos con PHP


Resultado Web:

Figura 144. Resultado de pagina25.php


Ejemplo 74:

Edicin de registro en PostgreSQL.

pagina26.php
<html>
<head>
<?php
include "pagina22.php";
$sql="select * from persona where idpersona='$_GET[idpersona]'";
$rs=pg_query($sql) or die(pg_last_error());
if(pg_num_rows($rs)>0) $registro=pg_fetch_array($rs);
?>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Edici&oacute;n de registro</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="pagina27.php">
<input type="hidden" name="idpersona" value="<?php echo
$_GET[idpersona]?>">
<table width="80%" border="0" align="center">
<tr> <th colspan="2">Edici&oacute;n de Persona</th> </tr>
<tr>
<td>Nombres</td> <td><input name="nombres" type="text"
id="nombres" size="50" maxlength="50" value="<?php echo
$registro[nombres]?>" /></td>
</tr>
<tr>
<td>Apellidos</td>
<td><input name="apellidos" type="text" id="apellidos" size="50"
maxlength="50" value="<?php echo $registro[apellidos]?>" /></td>
</tr>
<tr>
<td>E-Mail</td>
<td><input name="email" type="text" id="email" size="50"
maxlength="100" value="<?php echo $registro[email]?>"/></td>
</tr>
Oscar E Capuay Uceda

174

Acceso a Datos con PHP


<tr>
<td>Tel&eacute;fono</td>
<td><input name="telefono" type="text" id="telefono" maxlength="15"
value="<?php echo $registro[telefono]?>"/></td>
</tr>
<tr>
<th colspan="2"><input name="Submit" type="submit" class="boton"
value="Guardar" /> <input name="Submit2" type="button" class="boton"
value="Cancelar" onclick="location='pagina24.php'" /></th>
</tr>
</table>
</form>
</body>
</html>
Resultado Web:

Figura 145. Resultado de pagina26.php


pagina27.php
<?php
include "pagina22.php";
//sentencia para editar el registro
$sql="update persona set nombres='$_POST[nombres]',
apellidos='$_POST[apellidos]', email='$_POST[email]',
telefono='$_POST[telefono]' where idpersona='$_POST[idpersona]'";
pg_query($sql) or die(pg_last_error($conex));
echo "La persona fue actualizada exitosamente<br>";
echo "<a href='pagina24.php'>Listado de Personas</a>";
?>
Resultado Web:

Oscar E Capuay Uceda

175

Acceso a Datos con PHP

Figura 146. Resultado de pagina27.php


Ejemplo 75:

Eliminacin de registro en PostgreSQL.

pagina28.php
<?php
include "pagina22.php";
//sentencia para eliminar el registro
$sql="delete from persona where idpersona='$_GET[idpersona]'";
//ejecutar sentencia
pg_query($sql) or die(pg_last_error());
echo "La persona fue eliminada exitosamente<br>";
echo "<a href='pagina24.php'>Listado de Personas</a>";
?>

Figura 147. Resultado de pagina28.php

Oscar E Capuay Uceda

176

Acceso a Datos con PHP

Acceso a MS SQL-Server desde PHP


Ahora es el turno de MS SQLServer, para crear una base de datos vamos a
abrir el Administrador Corporativo y luego crearemos una base de datos
llamada dbdemo.

Figura 148. Creando un nueva base de datos

Figura 149. Nombre de la nueva base de datos

Oscar E Capuay Uceda

177

Acceso a Datos con PHP


Luego creamos la tabla persona.

Figura 150. Creando una nueva tabla

Figura 151. Especificacin de los campos de la tabla


Verificamos si la librera para MS-SQLServer est disponible.

Oscar E Capuay Uceda

178

Acceso a Datos con PHP

Figura 152. Activando la extensin php_mssql


Luego ingresamos algunos registros para probar los scripts.

Figura 153. Creando un usuario para acceso a la base de datos


Creamos un usuario para el acceso a la base de datos que hemos creado y
establecemos los permisos.

Oscar E Capuay Uceda

179

Acceso a Datos con PHP

Figura 154. Establecimiento de los permisos del usuario


Ejemplo 76:

Conexin a MS-SQLServer

pagina29.php
<?php
//conexion al servidor MS-SQLServer
$conex=mssql_connect("LAPTOP\\","oscar","123456") or die("Error en la
conexin");
mssql_select_db("dbdemo",$conex) or die("Error al seleccionar la BD");
?>
Ahora probemos listando los registros.
pagina30.php
<?php
include "pagina29.php"; //incluimos la conexion
//consulta sql
$sql="select * from persona";
//ejecucion de la sentencia sql
$rspersona=mssql_query($sql) or die("Error sql");
while($reg=mssql_fetch_array($rspersona)) {
echo $reg[idpersona]." - ".$reg[nombres]." ".$reg[apellidos]."<br>";
}
?>
Resultado Web:

Oscar E Capuay Uceda

180

Acceso a Datos con PHP

Figura 155. Resultado de pagina30.php


Ejemplo 77:

Listado de registros

pagina31.php
<?php
include "pagina29.php"; //incluimos la conexion
//consulta sql
$sql="select * from persona";
//ejecucion de la sentencia sql
$rspersona=mssql_query($sql) or die("error en la consulta");
?>
<table>
<tr>
<th>Id</th>
<th>Nombres</th>
<th>Apellidos</th>
<th>Editar</th>
<th>Eliminar</th>
</tr>
<?php
//mostrar los registros
while($registro=mssql_fetch_array($rspersona))
{ ?>
<tr>
<td><?php echo "$registro[idpersona]"?></td>
<td><?php echo "$registro[nombres]"?></td>
<td><?php echo "$registro[apellidos]"?></td>
<td><a href="pagina33.php?idpersona=<?php echo
"$registro[idpersona]"?>">editar</a></td>
<td><a href="pagina35.php?idpersona=<?php echo
"$registro[idpersona]"?>">eliminar</a></td>
</tr>
<?php
}
//Liberar conjunto de resultados
mssql_free_result($rspersona);
// Cerrar conexion
mssql_close($conex);
?>

Oscar E Capuay Uceda

181

Acceso a Datos con PHP


</table>
<br>
<a href="formulario07.html">Agregar Registro</a>

Ejemplo 78:

Insercin de registro en MS-SQLServer

formulario07.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Nuevo registro</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="pagina32.php">
<table width="80%" border="0" align="center">
<tr>
<th colspan="2">Nuevo Registro</th>
</tr>
<tr>
<td>Nombres</td> <td><input name="nombres" type="text"
id="nombres" size="50" maxlength="50" /></td>
</tr>
<tr>
<td>Apellidos</td> <td><input name="apellidos" type="text"
id="apellidos" size="50" maxlength="50" /></td>
</tr>
<tr>
<td>E-Mail</td> <td><input name="email" type="text" id="email"
size="50" maxlength="100" /></td>
</tr>
<tr>
<td>Tel&eacute;fono</td> <td><input name="telefono" type="text"
id="telefono" maxlength="15" /></td>
</tr>
<tr>
<th colspan="2"><input name="Submit" type="submit" class="boton"
value="Guardar" /> <input name="Submit2" type="button" class="boton"
value="Cancelar" onclick="location='pagina14.php'" /></th>
</tr>
</table>
</form>
</body>
</html>

Oscar E Capuay Uceda

182

Acceso a Datos con PHP


pagina32.php
<?php
include "pagina29.php";
//sentencia para insertar la persona
$sql="insert into persona (nombres, apellidos, email, telefono ) values
('$_POST[nombres]','$_POST[apellidos]','$_POST[email]','$_POST[telefono]'
)";
mssql_query($sql) or die("error al insertar el registro");
echo "La persona fue registrada exitosamente<br>";
echo "<a href='pagina31.php'>Listado de Personas</a>";
?>
Resultado Web:

Figura 156. Resultado de pagina32.php

Oscar E Capuay Uceda

183

Acceso a Datos con PHP


Ejemplo 79:

Edicin de registro en MS-SQLServer

pagina33.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php
include "pagina29.php";
$sql="select * from persona where idpersona='$_GET[idpersona]'";
$rs=mssql_query($sql) or die("error en la consulta");
//ejecutar sentencia
if(mssql_num_rows($rs)>0)
$registro=mssql_fetch_array($rs);
?>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Edici&oacute;n de registro</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="pagina34.php">
<input type="hidden" name="idpersona" value="<?php echo
$_GET[idpersona]?>">
<table width="80%" border="0" align="center">
<tr>
<th colspan="2">Edici&oacute;n de Persona</th>
</tr>
<tr>
<td>Nombres</td>
<td><input name="nombres" type="text" id="nombres" size="50"
maxlength="50" value="<?php echo $registro[nombres]?>" /></td>
</tr>
<tr> <td>Apellidos</td>
<td><input name="apellidos" type="text" id="apellidos" size="50"
maxlength="50" value="<?php echo $registro[apellidos]?>" /></td>
</tr>
<tr> <td>E-Mail</td>
<td><input name="email" type="text" id="email" size="50" maxlength="100"
value="<?php echo $registro[email]?>"/></td>
</tr>
<tr> <td>Tel&eacute;fono</td>
<td><input name="telefono" type="text" id="telefono" maxlength="15"
value="<?php echo $registro[telefono]?>"/></td>
</tr>
<tr>
<th colspan="2"><input name="Submit" type="submit" class="boton"
value="Guardar" /> <input name="Submit2" type="button" class="boton"
value="Cancelar" onclick="location='pagina31.php'" /></th>
</tr>
</table>
</form>
Oscar E Capuay Uceda

184

Acceso a Datos con PHP


</body>
</html>
Resultado Web:

Figura 157. Resultado de pagina33.php


pagina34.php
<?php
include "pagina29.php";
//sentencia para editar el registro
$sql="update persona set nombres='$_POST[nombres]',
apellidos='$_POST[apellidos]', email='$_POST[email]',
telefono='$_POST[telefono]' where idpersona='$_POST[idpersona]'";
//ejecutar sentencia
mssql_query($sql) or die("error al editar el registro");
echo "La persona fue actualizada exitosamente<br>";
echo "<a href='pagina31.php'>Listado de Personas</a>";
?>
Resultado Web:

Figura 158. Resultado de pagina34.php


Ejemplo 80:

Eliminacin de registros en MS-SQLServer

pagina35.php
<?php
include "pagina29.php";
//sentencia para eliminar el registro
$sql="delete from persona where idpersona='$_GET[idpersona]'";
//ejecutar sentencia
Oscar E Capuay Uceda

185

Acceso a Datos con PHP


mssql_query($sql) or die("Error al eliminar el registro");
echo "La persona fue eliminada exitosamente<br>";
echo "<a href='pagina31.php'>Listado de Personas</a>";
?>
Resultado Web:

Figura 159. Resultado de pagina35.php

Oscar E Capuay Uceda

186

PHP Orientado a Objetos

VI. PHP Orientado a Objetos


Clases en PHP
Cada definicin de clase empieza con la palabra "class", seguida por un
nombre de clase, el cual puede ser cualquier nombre que no est en la lista
de palabras reservadas en PHP. [3]
Ejemplo 81:

Definicin de una clase

pagina19.php
<?php
class MiClase
{
// Declaracin de un miembro de la clase
public $variable = 'demo'; // demo es el valor por defecto de $variable
// Declaracin de un mtodo
public function ver() {
echo $this->variable; //imprime el valor de $variable
}
}
?>

Instancia de un Objeto
Para crear una instancia de un objeto, un nuevo objeto debe ser creado y
asignado a una variable. Un objeto siempre ser asignado cuando se crea
un objeto nuevo a menos que el objeto tenga un constructor definido que
arroje una excepcin en caso de error. Las clases deben ser definidas antes
de crear las instancias (y en algunos casos esto es un requerido).
Cuando se asigna una instancia de un objeto previamente creado a una
nueva variable, la nueva variable accesar a la misma instancia que la del
objeto a la que fue asignada. Este comportamiento es el mismo cuando se
pasan instancias a una funcin. Una nueva instancia de un objeto
previamente creado puede ser hecha clonndolo. [3]
Ejemplo 82:

Creando una instancia

pagina20.php
<?php
include "pagina19.php"; //definicin de MiClase
//Creando una instancia
$instancia = new MiClase();
// Asignacin del Objeto
$asignado = $instancia;
$referencia =& $instancia;
Oscar E Capuay Uceda

187

PHP Orientado a Objetos


$instancia->variable = '$asignado tendr&aacute; este valor';
$instancia = null; // $instancia y $referencia sern nulos
var_dump($instancia);
var_dump($referencia);
var_dump($asignado);
?>
Resultado Web

Figura 160. Resultado de pagina20.php

Extendiendo objetos
Una clase puede heredar mtodos y miembros de otra clase usando la
palabra 'extends' en la declaracin. No es posible extender de mltiples
clases, una clase puede heredar solo de una clase base.
Los mtodos heredados y sus miembros pueden ser evitados,
redeclarndolos con el mismo nombre con el que los defini la clase padre, a
menos que la clase padre haya definido un mtodo como final. Es posible
accesar a los mtodos o miembros redeclarados haciendo referencia a ellos
con parent::
Ejemplo 83:

Herencia simple de una Clase

pagina21.php
<?php
include "pagina19.php";
class ExtendClass extends MiClase
{
// Redefinicin de mtodo
function ver()
{
echo "clase con nuevo m&eacute;todo\n";
parent::ver();
}
}
$extended = new ExtendClass();
$extended->ver();
?>

Oscar E Capuay Uceda

188

PHP Orientado a Objetos


Resultado Web

Figura 161. Resultado de pagina21.php

Auto carga de Objetos


Cuando se escriben aplicaciones con programacin orientada a objetos
crean un archivo fuente PHP por cada definicin de clase. Una de las
molestias ms grandes es tener que escribir una larga lista de includes
necesarios al principio de cada script (uno para cada clase).
En PHP 5, esto ya no es necesario. Puede definir una funcin __autoload la
cual es llamada automticamente en caso de que intente usar una clase que
no ha sido definida an. Al llamar esta funcin la ejecucin del script da una
ltima oportunidad de cargar la clase antes de que PHP falle con un error.
Nota: Las excepciones arrojadas en la funcin __autoload no pueden ser
capturadas en el bloque catch y resultan en el despliegue de un error fatal.
Nota: La autocarga no esta disponible en PHP si se usa el modo interactivo
CLI.
En el siguiente ejemplo se intenta cargar las clases clase1 y clase2 de los
archivos clase1.php y clase2.php respectivamente utilizando la funcin
__autoload para despus ejecutar los mtodos de cada clase.
Ejemplo 84:

Auto carga

clase1.php
<?php
class clase1
{
// Declaracin de un miembro de la clase
public $texto = 'esta es la clase1';
// Declaracin de un mtodo
public function mostrar() {
echo $this->texto; //imprime el valor de $variable
}
}
?>
Oscar E Capuay Uceda

189

PHP Orientado a Objetos


clase2.php
<?php
class clase2
{
// Declaracin de un miembro de la clase
public $mi_texto = 'texto de la clase2';
// Declaracin de un mtodo
public function display() {
echo $this->mi_texto; //imprime el valor de $variable
}
}
?>
autocarga.php
<?php
function __autoload($nombre_clase) {
require_once $nombre_clase . '.php';
}
$obj1 = new clase1();
$obj2 = new clase2();
$obj1->mostrar();
?>
<br>
<?php
$obj2->display();
?>
Resultado Web:

Figura 162. Resultado de autocarga.php

Oscar E Capuay Uceda

190

PHP Orientado a Objetos

Acceso a MySQL con PHP Orientado a Objetos


PHP 5.x viene con una extensin mejorada para trabajar con la funcionalidad
provista por MySQL 4.1 y superior.
Veamos a continuacin una breve referencia es clases y mtodos.
Clases predefinidas

mysqli
Representa una conexin entres PHP y la base de datos MySQL.
Constructor
mysqli - constructor de un nuevo objeto mysqli
Mtodos
autocommit - cambia en ON u OFF las modificaciones de auto-commiting en
la base de datos.
change_user - cambia el usuario del identificador de enlace especificado.
character_set_name - regresa el conjunto de caracteres del identificador de
enlace especificado.
close - cierra una conexin previamente abierta.
commit - completa la transaccin actual.
connect - abre una nueva conexin al servidor de MySQL.
debug - realiza operaciones de rastreo.
dump_debug_info - vaca informacin de rastreo.
get_client_info - retorna la versin del cliente.
get_host_info - retorna el tipo de conexin usada.
get_server_info - retorna la versin del servidor MySQL.
get_server_version - retorna la versin del servidor MySQL
init - inicializa el objeto mysqli.
info - obtiene informacin acerca de la consulta ms recientemente
ejecutada.
kill - solicita al servidor destruir un thread de mysql.
Oscar E Capuay Uceda

191

PHP Orientado a Objetos


multi_query - realiza consultas de SQL mltiples.
more_results - verifica si existen mas resultados de la consulta mltiple
actualmente ejecutada.
next_result - lee el siguiente resultado de la consulta mltiple actualmente
ejecutada.
options - fija opciones extra en la conexin.
ping - llama una conexin con el servidor o reconecta si no hay conexin.
prepare - prepara una sentencia SQL.
query - ejecuta una sentencia SQL.
real_connect - intenta abrir una conexin al servidor de base de datos
MySQL.
escape_string - caracteres especiales de escape para ser usados en una
sentencia SQL, tomando en cuenta el conjunto de caracteres actual de la
conexin.
rollback - deshace la transaccin actual.
select_db - selecciona la base de datos por defecto.
ssl_set - fija los parmetros SSL.
stat - obtiene el estado actual del sistema.
stmt_init - inicializa una sentencia para ser usada con mysqli_stmt_prepare.
store_result - transfiere un resultado de la ltima consulta.
use_result - transfiere un resultado sin almacenamiento intermedio de la
ltima consulta.
thread_safe - retorna si se ha dado thread_safety o no.
Propiedades
affected_rows - obtiene el nmero de filas afectadas en la operacin MySQL
previa.
client_info - retorna en una cadena la versin del cliente de MySQL.
client_version - retorna en un entero la versin del cliente de MySQL.
errno - retorna el cdigo de error para la llamada a funcin ms reciente.

Oscar E Capuay Uceda

192

PHP Orientado a Objetos


error - retorna la cadena de error para la llamada a funcin ms reciente.
field_count - retorna el nmero de columnas para la consulta ms reciente.
host_info - retorna la cadena representando el tipo de conexin usado.
info - retorna informacin acerca de la consulta ejecutada ms
recientemente.
insert_id - retorna el identificador generado automticamente usado en la
ltima consulta.
protocol_version - retorna la versin del protocolo usado por MySQL.
sqlstate - retorna una cadena que contiene el cdigo de error SQLSTATE
para el ltimo error.
thread_id - retorna el identificador del THREAD para la conexin actual.
warning_count - retorna el nmero de alertas generadas durante la ejecucin
del enunciado SQL previo.

mysqli_stmt
Representa una sentencia preparada.
Mtodos
bind_param - enlaza variables a una sentencia preparada.
bind_result - enlaza variables a una sentencia preparada para el
almacenamiento del resultado.
close - cierra la sentencia preparada.
data_seek - busca a una fila arbitrariamente en el resultado.
execute - ejecuta una sentencia preparada.
fetch - obtiene el resultado de la sentencia preparada en variables lmite.
free_result - libera la memoria del resultado almacenado para el manejador
de la sentencia dada.
result_metadata - obtiene un resultado de la sentencia preparada para
informacin de metadatos.
prepare - prepara una consulta SQL.
send_long_data - enva datos en partes.
reset - resetea una sentencia preparada.
Oscar E Capuay Uceda

193

PHP Orientado a Objetos


store_result - almacena el resultado completo de la sentencia preparada.

Propiedades
affected_rows - retorna las filas afectadas de la ltima sentencia ejecutada.
errno - retorna el cdigo de error para la llamada a funcin ms reciente.
error - retorna el mensaje de error para la llamada a funcin ms reciente.
param_count - retorna el numero de parmetros para la sentencia preparada
dada.
sqlstate - retorna una cadena conteniendo el cdigo de error SQLSTATE
para la llamada a funcin ms reciente.

mysqli_result
Representa el resultado obtenido de la consulta hecha en la base de datos.
Mtodos
close - cierra el resultado.
data_seek - mueve el puntero interno del resultado.
fetch_field - obtiene la informacin de la columna en el resultado.
fetch_fields - obtiene la informacin para todas las columnas del resultado.
fetch_field_direct - obtiene informacin de la columna para la columna dada.
fetch_array - recupera una fila como una matriz asociativa, una matriz
numrica, o ambos.
fetch_assoc - obtiene una fuka como una matriz asociativa.
fetch_object - obtiene una fila como un objeto.
fetch_row - obtiene una fila como una matriz enumerada.
close - libera la memoria ocupada por el resultado.
field_seek - fija el apuntador del resultado a la posicin especificada.
Propiedades
current_field - retorna la posicin de puntero actual.
field_count - retorna el nmero de campos en el resultado.

Oscar E Capuay Uceda

194

PHP Orientado a Objetos


lengths - retorna una matriz con la longitud de los campos.
num_rows - retorna el nmero de filas en el resultado.

Nos conectaremos a la base de datos dbdemo y administraremos la tabla


persona.

Ejemplo 85:

Conexin a MySQL con mysqli

mysqli-connect.php
<?php
$mysqli = new mysqli("localhost", "root", "", "dbdemo");
/* verifica la conexin */
if (mysqli_connect_errno()) {
printf("Conexin fallida:<br> %s\n", mysqli_connect_error());
exit();
}
printf("Server MySQL:<br> %s\n", $mysqli->host_info);
/* Cerrar la conexin */
$mysqli->close();
?>
Resultado Web:

Figura 163. Resultado de mysqli-connect.php


Modificaremos el archivo anterior para utilizarlo en las conexiones de las
prximas pginas.
mysqli-conexion.php
<?php
$mysqli = new mysqli("localhost", "root", "", "dbdemo");
/* verifica la conexin */
if (mysqli_connect_errno()) {
Oscar E Capuay Uceda

195

PHP Orientado a Objetos


printf("Error en la conexin:<br> %s\n", mysqli_connect_error());
exit();
}
?>

Ejemplo 86:

Listado con mysqli

mysqli-lista.php
<?php
include "mysqli-conexion.php"; //incluimos la conexin
//consulta sql
$sql="select * from persona";
//ejecucion de la sentencia sql
$rspersona=$mysqli->query($sql) or die($mysqli->error);
//listado
while($reg=$rspersona->fetch_object()) {
echo $reg->idpersona." - ".$reg->nombres." ".$reg->apellidos."<br>";
}
?>
Resultado Web:

Figura 164. Resultado de mysqli-lista.php


mysqli-listado.php
<?php
include "mysqli-conexion.php"; //incluimos la conexion
//consulta sql
$sql="select * from persona";
//ejecucion de la sentencia sql
$rspersona=$mysqli->query($sql) or die($mysqli->error);
?>
<table>
<tr>
<th>Id</th>
<th>Nombres</th>
<th>Apellidos</th>
Oscar E Capuay Uceda

196

PHP Orientado a Objetos


<th>Editar</th>
<th>Eliminar</th>
</tr>
<?php
//mostrar los registros
while($registro=$rspersona->fetch_object())
{ ?>
<tr>
<td><?php echo "$registro->idpersona"?></td>
<td><?php echo "$registro->nombres"?></td>
<td><?php echo "$registro->apellidos"?></td>
<td><a href="mysqli-editar.php?idpersona=<?php echo "$registro>idpersona"?>">editar</a></td>
<td><a href="mysqli-eliminar.php?idpersona=<?php echo "$registro>idpersona"?>">eliminar</a></td>
</tr>
<?php
}
$rspersona->close(); //cerramos resultado de la consulta
$mysqli->close(); //cerramos la conexin
?>
</table>
<br>
<a href="formulario08.html">Agregar Registro</a>
</body>
</html>
Resultado Web:

Figura 165. Resultado de mysqli-listado.php


Ejemplo 87:

Insercin de registro con mysqli

formulario08.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
Oscar E Capuay Uceda

197

PHP Orientado a Objetos


<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Nuevo registro</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="mysqli-insertar.php">
<table width="80%" border="0" align="center">
<tr> <th colspan="2">Nuevo Registro</th></tr>
<tr>
<td>Nombres</td> <td><input name="nombres" type="text"
id="nombres" size="50" maxlength="50" /></td>
</tr>
<tr>
<td>Apellidos</td> <td><input name="apellidos" type="text"
id="apellidos" size="50" maxlength="50" /></td>
</tr>
<tr>
<td>E-Mail</td> <td><input name="email" type="text" id="email"
size="50" maxlength="100" /></td>
</tr>
<tr>
<td>Tel&eacute;fono</td> <td><input name="telefono" type="text"
id="telefono" maxlength="15" /></td>
</tr>
<tr>
<th colspan="2"><input name="Submit" type="submit" class="boton"
value="Guardar" /> <input name="Submit2" type="button" class="boton"
value="Cancelar" onclick="location=' mysqli-listado.php'" /></th>
</tr>
</table>
</form>
</body>
</html>
Resultado Web:

Figura 166. Resultado de formulario08.htm


Oscar E Capuay Uceda

198

PHP Orientado a Objetos

mysqli-insertar.php
<?php
include "mysqli-conexion.php";
//sentencia para insertar el usuario
$sql="insert into persona
values('','$_POST[nombres]','$_POST[apellidos]','$_POST[email]','$_POST[t
elefono]')";
//ejecutar sentencia
$mysqli->query($sql) or die($mysqli->error);
echo "La persona fue registrada exitosamente<br>";
echo "<a href='mysqli-listado.php'>Listado de Personas</a>";
?>
Resultado Web:

Figura 167. Resultado de mysqli-insertar.php


Ejemplo 88:

Edicin de registro con mysqli

mysqli-editar.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php
include "mysqli-conexion.php";
$sql="select * from persona where idpersona='$_GET[idpersona]'";
$rs=$mysqli->query($sql) or die($mysqli->error);
//ejecutar sentencia
if($rs->num_rows>0)
$registro=$rs->fetch_object();
?>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Edici&oacute;n de registro</title>
</head>

Oscar E Capuay Uceda

199

PHP Orientado a Objetos


<body>
<form id="form1" name="form1" method="post" action="mysqliactualizar.php">
<input type="hidden" name="idpersona" value="<?php echo
$_GET[idpersona]?>">
<table width="80%" border="0" align="center">
<tr> <th colspan="2">Edici&oacute;n de Persona</th></tr>
<tr> <td>Nombres</td> <td><input name="nombres" type="text"
id="nombres" size="50" maxlength="50" value="<?php echo $registro>nombres?>" /></td>
</tr>
<tr><td>Apellidos</td> <td><input name="apellidos" type="text"
id="apellidos" size="50" maxlength="50" value="<?php echo $registro>apellidos?>" /></td></tr>
<tr>
<td>E-Mail</td> <td><input name="email" type="text" id="email"
size="50" maxlength="100" value="<?php echo $registro->email?>"/></td>
</tr>
<tr>
<td>Tel&eacute;fono</td> <td><input name="telefono" type="text"
id="telefono" maxlength="15" value="<?php echo $registro>telefono?>"/></td>
</tr>
<tr>
<th colspan="2"><input name="Submit" type="submit" class="boton"
value="Guardar" /> <input name="Submit2" type="button" class="boton"
value="Cancelar" onclick="location=' mysqli-listado.php'" /></th>
</tr>
</table>
</form>
<?php
$rs->close();
$mysqli->close();
?>
</body>
</html>
Resultado Web:

Figura 168. Resultado de mysqli-editar.php


Oscar E Capuay Uceda

200

PHP Orientado a Objetos


mysqli-actualizar.php
<?php
include "mysqli-conexion.php";
//sentencia para editar el registro
$sql="update persona set nombres='$_POST[nombres]',
apellidos='$_POST[apellidos]', email='$_POST[email]',
telefono='$_POST[telefono]' where idpersona='$_POST[idpersona]'";
//ejecutar sentencia
$mysqli->query($sql) or die($mysqli->error());
echo "La persona fue actualizada exitosamente<br>";
echo "<a href='mysqli-listado.php'>Listado de Personas</a>";
?>
Resultado Web:

Figura 169. Resultado de mysqli-actualizar.php


Ejemplo 89:

Eliminacin de registros con mysqli

mysql-eliminar.php
<?php
include "mysqli-conexion.php";
//sentencia para eliminar el registro
$sql="delete from persona where idpersona='$_GET[idpersona]'";
//ejecutar sentencia
$mysqli->query($sql) or die($mysqli->error());
echo "La persona fue eliminada exitosamente<br>";
echo "<a href='mysqli-listado.php'>Listado de Personas</a>";
?>
Resultado Web:

Figura 170. Resultado de mysqli-eliminar.php


Oscar E Capuay Uceda

201

PHP Orientado a Objetos

Paginando resultados
Ejemplo 90:

Paginacin de resultados

mysqli-listado-paginacion.php
<?php
include "mysqli-conexion.php"; //incluimos la conexion
//consulta sql
$sql="select * from persona";
//ejecucion de la sentencia sql
$rspersona=$mysqli->query($sql) or die($mysqli->error);
$numreg=$rspersona->num_rows;
$regxpag=3;
if(!isset($_GET['p']))$_GET['p']=1;
$inicio=$regxpag*($_GET['p']-1);
$sql=$sql ." limit $inicio,$regxpag";
$numpag=ceil($numreg/$regxpag);
$rspersona=$mysqli->query($sql) or die($mysqli->error);
echo "Registros encontrados:" . $numreg;
?>
<table>
<tr>
<th>Id</th>
<th>Nombres</th>
<th>Apellidos</th>
<th>Editar</th>
<th>Eliminar</th>
</tr>
<?php
//mostrar los registros
while($registro=$rspersona->fetch_object())
{ ?>
<tr>
<td><?php echo "$registro->idpersona"?></td>
<td><?php echo "$registro->nombres"?></td>
<td><?php echo "$registro->apellidos"?></td>
<td><a href="mysqli-editar.php?idpersona=<?php echo "$registro>idpersona"?>">editar</a></td>
<td><a href="mysqli-eliminar.php?idpersona=<?php echo "$registro>idpersona"?>">eliminar</a></td>
</tr>
<?php
}
$rspersona->close(); //cerramos resultado de la consulta
$mysqli->close(); //cerr=amos la conexin
?>
</table>
Oscar E Capuay Uceda

202

PHP Orientado a Objetos


P&aacute;gina:
<?php
for($i=1;$i<=$numpag;$i++) {
echo "<a href='mysqli-listado-paginacion.php?p=$i'>$i</a> ";
}
?>
<br>
<a href="formulario08.html">Agregar Registro</a>
Resultado Web:

Figura 171. Resultado de mysqli-listado-paginacion.php


Explicacin:
Primero incluimos el archivo para la conexin a la base de datos
include "mysqli-conexion.php"; //incluimos la conexin
Consultamos los registros de la tabla persona
//consulta sql
$sql="select * from persona";
//ejecucion de la sentencia sql
$rspersona=$mysqli->query($sql) or die($mysqli->error);
Hallamos la cantidad de registros de la tabla para dividirlo en pginas.
$numreg=$rspersona->num_rows;
Establecemos la cantidad de registros por pgina.
$regxpag=3;
Verificamos si la variable p que indica la pgina que se va a mostrar, tiene
algun valor. Si la variable no tiene valor, se le asigna 1 (pagina por defecto).
if(!isset($_GET['p']))$_GET['p']=1;
Hallamos el registro inicial de la pgina
$inicio=$regxpag*($_GET['p']-1);
Complementamos la sentencia SQL para mostrar solamente los registros de
la pgina seleccionada
Oscar E Capuay Uceda

203

PHP Orientado a Objetos


$sql=$sql ." limit $inicio,$regxpag";
Hallamos el nmero de pginas. La funcin ceil redondea fracciones hacia
arriba.
$numpag=ceil($numreg/$regxpag);
Ejecutamos la consulta SQL para obtener los registros de la pgina
seleccionada.
$rspersona=$mysqli->query($sql) or die($mysqli->error);
Imprimir la cantidad de registros total.
echo "Registros encontrados:" . $numreg;
En la parte inferior de la pgina web aparecen las pginas de resultados.
A travs de un bucle creamos los hipervnculos para visualizar las pginas.
<?php
for($i=1;$i<=$numpag;$i++) {
echo "<a href='mysqli-listado-paginacion.php?p=$i'>$i</a> ";
}

Oscar E Capuay Uceda

204

PHP Orientado a Objetos

Arquitectura MVC
Todos los que estamos inmersos en el mundo de la programacin sabemos
que en todo programa los datos que se procesan pueden ser ingresados y
mostrados en formas diferentes dependiendo del tipo y diseo de la interfaz,
y sobre todo en el desarrollo Web esto se ve aun ms acentuado debido a
que los desarrolladores Web muchas veces son muy buenos programando
pero no diseando interfaces, por lo general las empresas de este rubro
optan por utilizar dos equipos de trabajo: los codificadores quienes se
encargan de implementar los algoritmos y los diseadores para darle un
buena presentacin a la aplicacin, pero las dificultades inician cuando
alguna parte del cdigo que un equipo hace influye sobre el diseo que
realiza el otro equipo. Para dar solucin a este tipo de problemas han
surgido arquitecturas de desarrollo que nos permiten desarrollar aplicaciones
separando la lgica del diseo de la interfaz, una de ellas es la Arquitectura
MVC (Modelo Vista Controlador).

MVC con PHP


Lo que se muestra a continuacin es un artculo muy interesante extrado de
http://www.phpizza.com/es/ en el que se explica de una forma fcil y sencilla
el uso de MVC con PHP.
Esta arquitectura va ms all de esa divisin abstracta en dos capas e
implementa 3 partes:

Figura 172. MVC


Fuente: http://www.phpizza.com

En el esquema de arriba las flechas oscuras significan una interaccin


directa y las claras la indirecta. Esto bsicamente quiere decir que las verdes
son las respuestas a las azules.
Oscar E Capuay Uceda

205

PHP Orientado a Objetos


La capa de Presentacin se divide en dos componentes: Controlador y la
Vista. La capa de Datos tiene un componente: el Modelo.
Controlador
Algunos al hablar de Controlador se referirn a su acometido bajo los
nombres de Lgica de Negocio o Lgica Empresarial.
Lo de la lgica de negocio probablemente venga de los tiempos en los que
los programas sobre todo hacan cosas relacionadas con informes contables.
Como su propio nombre indica el Controlador controla lo que sucede a partir
de que se haya producido una interaccin por parte del usuario sobre la
Vista.
La Vista le comunica los eventos al Controlador. El Controlador usa el
Modelo para conseguir los datos o almacenarlos y por fin, el Controlador
vuelve a usar la Vista para comunicar al usuario que resultado provoc su
accin.
Modelo
El acometido de esta parte llamada Modelo es el Acceso A Datos. Al hablar
de Datos uno piensa en una Base de Datos o un Sistema de Gestin de
Bases de Datos (SGBD): MySQL, PostgreSQL, Oracle etc.
En realidad el Modelo encapsula la Capa de Acceso a Datos de tal forma
que se supone que nos podemos olvidar de que tipo de SGBD estamos
usando.
El Modelo, en realidad, es el objeto en s.
Vista
La tercera parte es la Vista. Es en realidad la Capa de Presentacin. Sirve
para que el usuario pueda interactuar a travs de los eventos con el
Controlador y tambin para que pueda ver los resultados. Estos resultados
sern aportados por el Controlador a travs del Modelo.
Esta es la diferencia con la simple programacin por capas (tambin llamada
escalonada o multi-escalonada) y sin conocerla se suelen confundir los
trminos.

Oscar E Capuay Uceda

206

PHP Orientado a Objetos

Figura 173. Tres capas


Fuente: http://www.phpizza.com

En una arquitectura de separacin por capas que es una manera de llevar


a cabo la separacin abstracta de 2 capas la Capa de Acceso a Datos
nunca interfiere directamente con la Vista. Lo hace siempre a travs del
Controlador. El Controlador interpreta los eventos que le llegan de la Vista,
usa los objetos o funciones de la Capa de Acceso A Datos y enva datos a la
Vista. Pero la Vista no ejecuta los mtodos de los objetos. En MVC, sin
embargo, la Vista s puede mostrar datos a travs de los mtodos de un
objeto que el Controlador le ha pasado.[5]
MVC Web
Traducido al mundo de la programacin Web paso por paso:
1. el Controlador recibe una peticin. Esto puede ocurrir de forma
directa poniendo el usuario en el navegador la URL del Controlador
http://localhost/controlador.php, o mediante un evento a travs de
una Vista ya renderizada (envo de un formulario por ejemplo), o por
una peticin ajax.
2. el Controlador analiza la peticin y usa un Modelo para obtener
datos de algn tipo.
3. el Modelo puede leer datos y/o escribirlos en una base de datos.
Normalmente sucede esto, aunque no siempre.
4. el Controlador usa una Vista para poder presentar los resultados al
usuario.

Oscar E Capuay Uceda

207

PHP Orientado a Objetos


5. la Vista usa el Modelo, de tal forma, que algn tipo de respuesta
obtenido por la accin previa ser presentado en la Vista.
6. la Vista est renderizada con los datos del Modelo y el Controlador
enva esta respuesta al usuario.
7. El usuario obtiene la respuesta
El Modelo Vista Controlador no es una cosa reciente. Lo inventaron en los
aos 70 al empezar a hacer aplicaciones medianamente grandes que
manejaban muchos datos. Es el llamado Modelo* 2 en la jerga Sun.
*Aqu la palabra Modelo no tiene que ver con el Modelo de Modelo Vista
Controlador sino con el nombre de la arquitectura.
Hablando de la interaccin entre el Modelo y la Vista - en Java tambin es
posible implementar un componente llamado Observador que despus de
constatar algn cambio en el Modelo, puede realizar ciertas operaciones. Por
ejemplo: el usuario confirma la compra en una tienda on-line y el Observer
implementado ve que hay un cambio en el Modelo (en la propia base de
datos) y manda un email de confirmacin o actualiza la Vista.
Pero los Observadores no se implementan en PHP porque este lenguaje se
ejecuta de manera distinta a como se ejecutan los procesos de Java.
Normalmente al tener un tiempo limitado de ejecucin los procesos PHP no
hacen de observadores.
Sinceramente - hacer una aplicacin usando la arquitectura MVC te costar
ms trabajo que si haces pginas monolticas, mezclndolo todo - el php y el
html en lo que se llama popularmente el cdigo spaghetti.
El MVC supone ms trabajo:
Primero tendrs que definir los Modelos y convertirlos en Objetos de tal
manera que sus atributos y mtodos sean el conjunto de propiedades y
acciones verdaderamente necesarias y representativas. Tendrs que
planificar las Vistas por separado y trabajar los Controladores. Al principio de
la implementacin te ser ms rpido hacer pginas monolticas
Por qu usarlo entonces?
Pues, cuando quieras cambiar tu aplicacin para aadir, quitar o cambiar
alguna funcionalidad - la vida te resultar muy dura. Un proyecto
medianamente grande se convertir en un infierno en muy poco tiempo
sobre todo cuando quieras cambiar algo y ello afecte al funcionamiento de
ms de una de tus pginas.
El MVC bsicamente te permitir poder cambiar las Capas de presentacin
sin que afecten a la de acceso de datos y viceversa.
Hay gente que te dir que el PHP fue concebido como algo sencillo y
prctico. Como un lenguaje que permite hacer pginas Web dinmicas y
Oscar E Capuay Uceda

208

PHP Orientado a Objetos


procesar formularios de una manera simple. Que complicar las cosas ms
all de eso es impropio de este lenguaje.
Y les doy la razn. Claro! El asunto es que ese primer PHP no tena mucho
que ver con el PHP5 actual. No haba objetos por ejemplo.
Hay pequeas diferencias en como implementan el MVC distintos
frameworks, pero los fundamentos son los mismos.
Tambin puedes usar motores de plantillas como por ejemplo Smarty para
implementar el MVC, pero en realidad no necesitas nada ms que el PHP
puro.
Ejemplo 91:

MODELO MVC con PHP

_modelo.php
<?php
class ClaseX
{
protected $plantilla_propia = "_listar.php";
protected $arrayx= array();
public function show()
{
include ($this->plantilla_propia);
}//fun
public function CargarDatos()
{
$this->arrayx = array("Abel", "Marco","Pedro");
}//fun
}//class
?>
Ejemplo 92:

Una plantilla usada por el modelo

_listar.php
<?php
foreach ($this->arrayx as $elemento)
{
echo $elemento["nombre"];
echo "";
}//foreach
?>
Oscar E Capuay Uceda

209

PHP Orientado a Objetos


Ejemplo 93:

CONTROLADOR MVC con PHP

_controlador.php
<?php
include ("./_modelo.php");
$objX = new ClaseX();
//aqu habra que implementar una clase que
//determine las caracteristicas de la pagina
//pero para poner un ejemplo sencillo vamos
//a saltarnos esa parte en este artculo
$titulo = "pagina nueva";
$objX->CargarDatos();
include ("_vista.php");
?>
Ejemplo 94:

VISTA MVC con PHP

_vista.php
<html>
<head>
<title><?php echo $titulo; ?></title>
</head>
<body>
<?php $objX->show(); ?>
</body>
</html>
El punto clave en una Vista como la de este ejemplo es que no uses
instrucciones PHP ms all de las que muestren datos. Por qu? Pues si la
lgica de tu aplicacin se est decidiendo en la Vista entonces para qu
queremos el Controlador? ;) Simplificando mucho el concepto eso quiere
decir que uses echo y metodos de tus objetos (Modelo) que hagan echo de
alguna forma aunque tu los llames show o muestra_datos o lo que t
quieras.
El inventor y gur del PHP Rasmus Lerdorf, public hace algn tiempo, en
febrero del ao 2006 un bastante mal entendido artculo, titulado The no
framework PHP MVC framework
Aqu, Rasmus nos habla sobre como implementar un sencillo MVC usando
solo PHP puro. Bueno, estoy de acuerdo hasta un cierto punto con este
artculo y es que implementar el MVC sin usar un framework que vaya ms
all de nuestras necesidades nos va a beneficiar en cuanto a la memoria que
usa cada script PHP. Ms tarde hablaremos sobre la optimizacin. Algunos
Oscar E Capuay Uceda

210

PHP Orientado a Objetos


han interpretado que Rasmus en este artculo defenda la programacin
procedural en contra de la Orientada a Objetos. El mismo dice que no es asque poda haber hecho todo el ejemplo usando ms objetos y estoy de
acuerdo.
Pero si observas detenidamente la parte titulada View add.html que es el
ejemplo de Vista que nos pone su autor, te dars cuenta que la Vista hace al
principio una inclusin del Controlador:
include './ui.inc';

// Common View Helper functions

include './add_c.inc'; // Controller


head();
Vale, pues eso no es MVC aunque lo diga mi admirado Rasmus. Es un
framework con divisin de capas en tres partes pero no es MVC. La Vista no
debe ser la que controla la aparicin de un Controlador sino todo lo contrario:
el Controlador usa las Vistas.

Oscar E Capuay Uceda

211

PHP Orientado a Objetos

MVC y PHP con acceso a Base de Datos


Tomando como gua el artculo anterior desarrollaremos un listado de los
registros de la tabla persona creada en la seccin anterior.
Ejemplo 95:

modelo_bd.php

<?php
class BaseDatos
{
protected $servidor="localhost";
protected $usuario="root";
protected $password="";
protected $link;
public $rs;
public function conectar()
{
$this->link=mysql_connect($this->servidor,$this>usuario,$this->password) or die(mysql_error());
mysql_select_db("dbdemo",$this->link) or die(mysql_error());
}
public function consultar($sql)
{
$this->rs=mysql_query($sql) or die(mysql_error());
}
} //fin clase
class ClaseDatos
{
protected $plantilla_listado = "lista_bd.php";
protected $data= array();
protected $recset;
protected $registro;
*

public function show()


{
include ($this->plantilla_listado);
}

public function leer_registro()


{
$this->registro=mysql_fetch_array($this>recset,MYSQL_ASSOC) or die(mysql_error());
return $this->registro;
}

Oscar E Capuay Uceda

212

PHP Orientado a Objetos


public function CargarDatos($sentencia)
{
$objBase = new BaseDatos();
$objBase->conectar();
$objBase->consultar($sentencia);
$this->recset=$objBase->rs;
}
} //fin clase
?>
Ejemplo 96:

lista_bd.php

<table border="1">
<?php
while($this->leer_registro()) { ?>
<tr>
<?php
foreach($this->registro as $k => $v){
?>
<td><?php echo $this->registro[$k]?></td>
<?php
}
?>
</tr>
<?php } ?>
</table>
Ejemplo 97:

vista_bd.php

<html>
<head>
<title><?php echo $titulo; ?></title>
</head>
<body>
<?php $objData->show(); ?>
</body>
</html>
Ejemplo 98:

controlador_bd.php

<?php
include ("modelo_bd.php");
$objData = new ClaseDatos();
$sql="select * from persona";
Oscar E Capuay Uceda

213

PHP Orientado a Objetos


$titulo = "Lista de personas";
$objData->CargarDatos($sql);
include ("vista_bd.php");
?>
Para ver el resultado abrimos en navegador el archivo controlador_bd.php.

Figura 174. Resultado de controlador_bd.php

Oscar E Capuay Uceda

214

PHP Orientado a Objetos

PDO PHP Data Object


PHP Data Objects (PDO) es una extensin de PHP que utilice controladores
para acceder a datos de motores de bases de datos diversos como: MySQL,
PostgreSQL, Microsoft SQL Server, Oracle, mSQL, etc.
PDO provee una capa de abstraccin de datos, con la cual, la codificacin
depende menos de la base de datos que estemos utilizando, debido a que
los mtodos tienen el mismo nombre para todas las bases de datos que
soporta, es decir, ya no tendremos que escribir mysql_query para ejecutar
una sentencia SQL en MySQL y cuando migremos a PostgreSQL tengamos
que cambiarla a pg_query.
PDO esta disponible desde PHP 5.1, y requiere las nuevas caractersticas de
programacin orientada a objetos que viene desde PHP 5, por lo que no
corre en versiones anteriores.
Los siguientes controladores estn disponibles actualmente:
Tabla 20.

Controladores PDO

Controlador

Base de Datos

PDO_DBLIB

FreeTDS / Microsoft SQL Server / Sybase

PDO_FIREBIRD

Firebird/Interbase 6

PDO_IBM

IBM DB2

PDO_INFORMIX

IBM Informix Dynamic Server

PDO_MYSQL

MySQL 3.x/4.x/5.x

PDO_OCI

Oracle Call Interface

PDO_ODBC

ODBC v3 (IBM DB2, unixODBC and win32 ODBC)

PDO_PGSQL

PostgreSQL

PDO_SQLITE

SQLite 3 and SQLite 2

Clases predefinidas

PDO
Representa una conexin entre PHP y un servidor de base de datos.
Constructor
PDO - construye un nuevo objeto PDO
Mtodos
beginTransaction inicia una transaccin.
commit - efecta la transaccin.

Oscar E Capuay Uceda

215

PHP Orientado a Objetos


errorCode retorna un cdigo de error, si ocurre alguno en la base de datos.
errorInfo retorna un arreglo de informacin del error, si ocurre alguno en la
base de datos.
exec ejecuta una sentencia SQL y retorna el nmero de registros
afectados.
getAttribute retorna los atributos de una conexin.
lastInsertId retorna el valor del ID del ultimo registro que fue insertado en la
tabla.
prepare - prepara una sentencia SQL para su ejecucin.
query ejecuta una sentencia SQL y retorna un conjunto de registros.
quote retorna una cadena de texto con comillas para su uso en sentencias
SQL. Recomendada para evitar inyeccin SQL.
rollBack - Deshace una transaccin
setAttribute establece un atributo para la conexin a una base de datos.

PDOStatement
Representa una sentencia preparada, luego que la sentencia es ejecutada,
un conjunto de registros.
Mtodos
bindColumn - relaciona variable a una columna de salida en un conjunto de
registros.
bindParam - relaciona una variable PHP a un parmetro en la sentencia
preparada.
bindValue - binds un valor a un parmetro en la sentencia preparada.
closeCursor - cierra el cursor, permitiendo ejecutar nuevamente la sentencia.
columnCount - retorna el nmero de columnas del conjunto de registros.
errorCode - retorna un cdigo de error, si lo hay, de la sentencia.
errorInfo - retorna un arreglo de informacin de un error, si lo hay, de la
sentencia.
execute ejecuta la sentencia preparada.
fetch lee un registro de un conjunto de registros.

Oscar E Capuay Uceda

216

PHP Orientado a Objetos


fetchAll asigna a un arreglo el contenido de todos los datos de un conjunto
de registros.
fetchColumn - retorna el dato de una columna en un conjunto de registros.
getAttribute retorna un atributo de un PDOStatement.
getColumnMeta retorna los metadatos de una columna en un conjunto de
resultados.
nextRowset retorna el siguiente registro.
rowCount - retorna el nmero de registros afectados por la ejecucin de la
sentencia SQL.
setAttribute establece un atributo PDOStatement.
setFetchMode establece el modo de lectura de registros de un
PDOStatement.

Oscar E Capuay Uceda

217

PHP Orientado a Objetos

Conexiones con PDO


Para establecer una conexin a una base de datos debemos instanciar la
clase PDO e indicar primero el nombre del motor de base de datos al cual
nos conectaremos, seguido del nombre del servidor, nombre de la base de
datos, usuario y finalmente la contrasea. En el siguiente podemos observar
una conexin a MySQL y las siguientes lneas que estn comentadas se
conectan a Microsoft SQL Server y a PostgreSQL respectivamente.
Ejemplo 99:

Conexin a MySQL con PDO

pdo-connect.php
<?php
$conn = new PDO('mysql:host=localhost;dbname=dbdemo',"root","");
//$conn = new PDO('mssql:host=localhost;dbname=dbmicro',"sa","");
//$conn = new PDO('pgsql:host=localhost;dbname=dbpos',"postgres","psql");
?>
Ahora veremos una lista simple obtenida de la tabla persona.
Ejemplo 100:

Lista de personas con PDO y manejo de errores

pdo-lista.php
<?php
try {
include "pdo-connect.php";
foreach ($conn->query('SELECT * from persona') as $registro) {
print_r($registro);
}
$conn = null; //cierre de conexin
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
?>

Oscar E Capuay Uceda

218

PHP Orientado a Objetos


Resultado Web

Figura 175. Resultado de pdo-lista.php


Ejemplo 101:

Listado de registros con PDO, con eliminacin mltiple

pdo-listado.php
<?php
include "pdo-connect.php"; //incluimos la conexion
//consulta sql
$sql="select * from persona";
$rspersona=$conn->query($sql);
?>
<form name="form1" action="pdo-eliminar.php" method="post">
<table>
<tr>
<th>Eliminar</th>
<th>Id</th>
<th>Nombres</th>
<th>Apellidos</th>
<th>Editar</th>
</tr>
<?php
//mostrar los registros
while($registro=$rspersona->fetch())
{ ?>
<tr>
<td><input
type="checkbox"
name="chkelim[]"
value="<?php
$registro[idpersona]?>" /></td>
<td><?php echo $registro[idpersona]?></td>
<td><?php echo $registro[nombres]?></td>
<td><?php echo $registro[apellidos]?></td>
<td><a
href="pdo-editar.php?idpersona=<?php
$registro[idpersona]?>">editar</a></td>
</tr>
<?php
Oscar E Capuay Uceda

echo

echo

219

PHP Orientado a Objetos


}
$rspersona->closeCursor(); //cerramos resultado de la consulta
$conn=null; //cerramos la conexin
?>
<tr>
<th><input type="submit" value="Eliminar" /></th>
<th colspan="4"><input type="button" onclick="location='pdo-nuevo.php'"
value="Nuevo" /></th>
</tr>
</table>
</form>
Resultado Web

Figura 176. Resultado de pdo-listado.php


Ejemplo 102:

Insercin de registros con PDO

pdo-nuevo.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Nuevo registro</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="pdo-insertar.php">
<table width="80%" border="0" align="center">
<tr>
<th colspan="2">Nuevo Registro</th>
</tr>
<tr>
<td>Nombres</td>
<td><input name="nombres" type="text" id="nombres" size="50"
maxlength="50" /></td>
Oscar E Capuay Uceda

220

PHP Orientado a Objetos


</tr>
<tr><td>Apellidos</td>
<td><input name="apellidos" type="text" id="apellidos" size="50"
maxlength="50" /></td>
</tr>
<tr><td>E-Mail</td>
<td><input
name="email"
type="text"
id="email"
size="50"
maxlength="100" /></td>
</tr>
<tr><td>Tel&eacute;fono</td>
<td><input name="telefono" type="text" id="telefono" maxlength="15"
/></td>
</tr>
<tr><th colspan="2"><input name="Submit" type="submit" class="boton"
value="Guardar" />
<input name="Submit2" type="button" class="boton" value="Cancelar"
onclick="location='mysqli-listado.php'" /></th>
</tr>
</table>
</form>
</body>
</html>

Resultado Web:

Figura 177. Resultado de pdo-nuevo.php

Ejecucin de Sentencias Preparadas con PDO


pdo-insertar.php
<?php
try {
include "pdo-connect.php";
$sentencia = $conn->prepare("INSERT INTO persona (nombres, apellidos,
email, telefono) VALUES (:nombres, :apellidos, :email, :telefono)");
Oscar E Capuay Uceda

221

PHP Orientado a Objetos


$sentencia->bindParam(':nombres', $_POST[nombres]);
$sentencia->bindParam(':apellidos', $_POST[apellidos]);
$sentencia->bindParam(':email', $_POST[email]);
$sentencia->bindParam(':telefono', $_POST[telefono]);
$sentencia->execute();
$conn = null;
header("location: pdo-listado.php");
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
?>
Ejemplo 103:

Eliminacin mltiple de registros con PDO

pdo-eliminar.php
<?php
include "pdo-connect.php";
$sentencia=$conn->prepare("delete from persona where idpersona=:id");
$sentencia->bindParam(':id',$valor);
foreach($_POST[chkelim] as $indice => $valor) {
$sentencia->execute();
}
header("location: pdo-listado.php");
?>
Ejemplo 104:

Edicin de registros con PDO.

pdo-editar.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<?php
include "pdo-connect.php";
$sql="select * from persona where idpersona=" . $_GET[idpersona];
$rspersona=$conn->query($sql);
$registro=$rspersona->fetch();
?>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Edici&oacute;n de registro</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="pdo-actualizar.php">
Oscar E Capuay Uceda

222

PHP Orientado a Objetos


<input
type="hidden"
name="idpersona"
value="<?php
echo
$_GET[idpersona]?>">
<table width="80%" border="0" align="center">
<tr><th colspan="2">Edici&oacute;n de Persona</th> </tr>
<tr><td>Nombres</td>
<td><input name="nombres" type="text" id="nombres" size="50"
maxlength="50" value="<?php echo $registro[nombres]?>" /></td></tr>
<tr><td>Apellidos</td>
<td><input name="apellidos" type="text" id="apellidos" size="50"
maxlength="50" value="<?php echo $registro[apellidos]?>" /></td></tr>
<tr><td>E-Mail</td>
<td><input
name="email"
type="text"
id="email"
size="50"
maxlength="100" value="<?php echo $registro[email]?>"/></td></tr>
<tr><td>Tel&eacute;fono</td>
<td><input name="telefono" type="text" id="telefono" maxlength="15"
value="<?php echo $registro[telefono]?>"/></td></tr>
<tr><th colspan="2"><input name="Submit" type="submit" class="boton"
value="Guardar" />
<input name="Submit2" type="button" class="boton" value="Cancelar"
onclick="location='pdo-listado.php'" /></th></tr>
</table>
</form>
<?php
$rspersona->closeCursor();
$conn=null;
?>
</body>
</html>
Resultado Web:

Figura 178. Resultado de pdo-editar.php


pdo-actualizar.php
<?php
include "pdo-connect.php";

Oscar E Capuay Uceda

223

PHP Orientado a Objetos


$sentencia = $conn->prepare("UPDATE persona SET nombres=:nombres,
apellidos=:apellidos,
email=:email,
telefono=:telefono
where
idpersona=:idpersona");
$sentencia->bindParam(':idpersona', $_POST[idpersona]);
$sentencia->bindParam(':nombres', $_POST[nombres]);
$sentencia->bindParam(':apellidos', $_POST[apellidos]);
$sentencia->bindParam(':email', $_POST[email]);
$sentencia->bindParam(':telefono', $_POST[telefono]);
$sentencia->execute();
$conn = null;
header("location: pdo-listado.php");
?>

Oscar E Capuay Uceda

224

Seguridad Web

VII. Seguridad Web


Las aplicaciones Web por lo general estn en lnea y eso las expone a la
visita de usuarios que llegan con objetivos distintos, uno de ellos el hacerse
de fama violando la seguridad de sitios Web, valindose de diferentes
estrategias y herramientas. Construir una aplicacin completamente segura
es imposible por tal motivo es imprescindible conocer y establecer barreras
contra estos ataques y por otro lado desarrollar las aplicaciones evitando
cometer errores en la codificacin desde el punto de vista lgico, que nos
puedan causar problemas de seguridad posteriormente, todo esto
minimizar en lo posible la posibilidad de violacin en la seguridad del
sistema, tal como se menciona en las recomendaciones generales de
seguridad en PHP:
Cuando realice pruebas, tenga en mente que no ser capaz de
probar todas las diferentes posibilidades, incluso para las
pginas ms simples. Los datos de entrada que usted puede
esperar en sus aplicaciones no necesariamente tendrn relacin
alguna con el tipo de informacin que podra ingresar un
empleado disgustado, un cracker con meses de tiempo entre sus
manos, o un gato domstico caminando sobre el teclado. Es por
esto que es mejor observar el cdigo desde una perspectiva
lgica, para determinar en dnde podran introducirse datos
inesperados, y luego hacer un seguimiento de cmo esta
informacin es modificada, reducida o amplificada.1
A continuacin veremos algunos temas sobre la seguridad en el desarrollo
Web.

Seguridad en el Sistema de archivos


El sistema de archivos en todo sistema operativo es importante debido a que
a travs de l se puede violar la seguridad de un computador, por ejemplo a
continuacin veremos un caso en el que un usuario puede borrar un archivo
importante del sistema operativo UNIX o LINUX debido a que no se tomaron
ciertas medidas de precaucin.
Ejemplo 105:

Borrar un archivo de un usuario

Este caso presenta el supuesto que un usuario ingresa su nombre y el


nombre de su archivo que desea eliminar de su directorio personal a travs
de la Web.
El usuario ingresar los datos en un formulario y los enviar al siguiente
archivo PHP.
<?php
// datos enviados a travs del formulario
$usuario = $_POST['nombre_usuario'];

http://www.php.net/manual/es/security.general.php

Oscar E Capuay Uceda

225

Seguridad Web
$archivo = $_POST['archivo'];
//generamos la ruta para el borrado del archivo directorio del usuario
$directorio = "/home/$usuario";
//orden de eliminacin del archivo
unlink("$directorio/$archivo");
echo "El archivo: $archivo ha sido eliminado!";
?>
Si alguien desea atacar el sistema de archivos podra escribir en el
formulario datos para eliminar por ejemplo el archivo de passwords del
sistema operativo, en el caso que PHP tuviera acceso de root.
Ejemplo 106:

Ataque mediante el borrado de archivos

<?php
// Para el caso del nombre del usuario enviamos: "../etc"
// Para el caso del nombre del archivo enviamos: "passwd"
$usuario = $_POST['nombre_usuario'];
$archivo = $_POST['archivo'];
//generando la ruta del directorio obtendramos lo siguiente: "/home/../etc"
$directorio = "/home/$nombre_usuario";
// El archivo que se va a eliminar es: "/home/../etc/passwd"
unlink("$directiorio/$archivo");
echo "El archivo ha sido eliminado!";
?>
Para mejorar el control y la validacin de los datos enviados por el usuario
utilizaremos funciones que nos permitan verificar el tipo de datos correcto.
Por ejemplo:
if
(!ctype_alnum($nombre_usuario)
||
!preg_match('/^(?:[a-z0-9_]|\.(?!\.))+$/iD', $archivo_usuario)) {
die("Nombre de usuario o archivo incorrecto");
}
ctype_alnum: es una funcin que devuelve TRUE cuando la cadena contiene
solamente caracteres alfanumricos, es decir, letras y/o nmeros.
preg_match: es una funcin que realiza una comparacin en base a una
expresin regular.

Oscar E Capuay Uceda

226

Seguridad Web

Seguridad en Base de datos


La seguridad de las aplicaciones Web tambin pasa por la etapa de diseo
de la base de datos, al momento de establecer los tipos de usuarios y los
privilegios que cada uno tendr, es recomendable hacer esto y no dejar todo
el control en la lgica de la aplicacin.
Respecto a la conexin con la base de datos es posible utilizar el protocolo
SSL para encriptar la comunicacin entre el servidor y los clientes, pero
solamente cifra la informacin en el medio, y no cuando es almacenada en la
base de datos.
Para el caso del almacenamiento de contraseas en la base de datos
recomiendo el uso de uno de los resmenes criptogrficos ms utilizados en
la actualidad: MD5.
En PHP el hash MD5 (acrnimo de Message-Digest Algorithm 5, Algoritmo
de Resumen del Mensaje 5) puede ser utilizado a travs de la funcin con el
mismo nombre: md5().MD5 es uno de los algoritmos de reduccin
criptogrficos diseados por el profesor Ronald Rivest del MIT
(Massachusetts Institute of Technology, Instituto Tecnolgico de
Massachusetts). Fue desarrollado en 1991 como reemplazo del algoritmo
MD4 despus de que Hans Dobbertin descubriese su debilidad. Veamos un
ejemplo:
Ejemplo 107:

Md5

md5.php
<?php
$texto="miclavedeacceso";
$cifrado=md5($texto);
echo "mi clave cifrada es:".$cifrado;
// el texto cifrado con MD5 de 128bits genera una cadena de 32 caracteres
de longitud.
?>
Resultado Web:

Figura 179. Resultado de md5.php


Una cualidad de este algoritmo es que no tiene funcin para descifrar lo que
lo hace mas seguro que otros debido a que un administrador de base de
datos no podra, por ejemplo, ver las claves de los usuarios.

Oscar E Capuay Uceda

227

Seguridad Web
Desarrollaremos ahora un formulario para el acceso de usuarios teniendo
como supuesto que la tabla de usuarios se llama: user, y los campos donde
estn registrados
los nombres de usuario y clave de acceso son:
user_nombre y user_clave respectivamente.
El script para este caso sera:
Ejemplo 108:

Script para acceso de usuarios

acceso-md5.php
<?php
include "conexion.php"; //conexion a la BD
//datos provenientes del formulario
$usuario=$_POST[txtusuario];
$clave=$_POST[txtclave];
$clave_cifrada=md5($clave);
$sql="select * from user
user_clave='".$clave_cifrada."'";

where

user_nombre='".$usuario."'

and

$rs=mysql_query($sql) or die(mysql_error());
//si existe un usuario con dichos datos
if(mysql_num_rows($rs)==1) echo "Datos correctos";
else echo "Datos incorrectos";
?>
Con este script no sera suficiente para dar la seguridad adecuada a nuestra
aplicacin Web. A continuacin veremos otro punto importante que debemos
tomar en cuenta.

Oscar E Capuay Uceda

228

Seguridad Web

Inyeccin SQL
Una consulta SQL no es una orden confiable a la que no se le debe prestar
la atencin debida, sino por el contrario es en la que ms cuidado debemos
tener puesto que a travs de ella se puede burlar los controles de acceso a
cualquier sistema Web e incluso permitir el acceso a comandos del sistema
operativo.
La Inyeccin de comandos SQL es una tcnica utilizada para alterar
comandos SQL definidos en una aplicacin con la finalidad de mostrar datos,
sobrescribirlos, eliminarlos o ejecutar rdenes que no fueron establecidas
por el desarrollador. La manera de realizar las alteraciones es a travs de los
datos enviados por un usuario y su combinacin con parmetros utilizados
en las sentencias SQL. A continuacin veremos ejemplos que nos ayudarn
a ver estos casos con mayor detalle.
Ejemplo 109:

Inyeccin SQL en una sentencia SELECT

<?php
$sql="SELECT
zona=$zona";

nombre,

apellidos,

direccion

FROM

cliente

WHERE

$result = mysql_query($sql);
?>
En este ejemplo la variable $zona es enviada por el usuario. Utilizando la
variable $zona enviaremos la siguiente cadena: union select * from usuario
-En la cadena podemos ver una comilla simple ( ) al inicio y doble guin ( -- )
al final.
Si reemplazamos esta cadena en lugar de la variable $zona veremos que el
resultado de la consulta mostrar todos los datos registrados en la tabla
usuario.
Utilizando como base el ejemplo anterior haremos inyeccin SQL en una
pgina con un listado que utiliza hipervnculos para la paginacin de
resultados.
Ejemplo 110:

Paginacin de resultados con Inyeccin SQL

inyeccion01.php
<?php
include "mysqli-conexion.php"; //incluimos la conexion
$cantidad=2; //numero de registros por pagina
//verificamos si existe la variable
Oscar E Capuay Uceda

229

Seguridad Web
if(!isset($_GET[p])) $_GET[p]=0;
//hallamos el total de registros
$sql="select * from persona";
$rspersona=$mysqli->query($sql) or die($mysqli->error);
$nr=$rspersona->num_rows;
//paginacin de resultados
$sql="select idpersona,nombres,apellidos from persona limit " . $_GET[p] .
",$cantidad";
$rspersona=$mysqli->query($sql) or die($mysqli->error);
?>
<table>
<tr>
<th>Id</th>
<th>Nombres</th>
<th>Apellidos</th>
<th>Editar</th>
<th>Eliminar</th>
</tr>
<?php
//mostrar los registros
while($registro=$rspersona->fetch_object())
{ ?>
<tr>
<td><?php echo "$registro->idpersona"?></td>
<td><?php echo "$registro->nombres"?></td>
<td><?php echo "$registro->apellidos"?></td>
<td><a
href="mysqli-editar.php?idpersona=<?php
echo
"$registro>idpersona"?>">editar</a></td>
<td><a
href="mysqli-eliminar.php?idpersona=<?php
echo
"$registro>idpersona"?>">eliminar</a></td>
</tr>
<?php
}
?>
<tr><td colspan="5">P&aacute;gina:
<?php
for($i=1;$i<=ceil($nr/$cantidad);$i++)
{
$inicio=$cantidad*($i-1);
echo "<a href='?p=$inicio'>$i</a> ";
}
?>
</td></tr>
</table>
<br>
<a href="formulario08.html">Agregar Registro</a>
<?php
$rspersona->close(); //cerramos resultado de la consulta
$mysqli->close(); //cerramos la conexin
?>

Oscar E Capuay Uceda

230

Seguridad Web
Resultado Web:

Figura 180. Resultado de inyeccion01.php


Ahora hagamos clic en la pgina 2. (Ver la direccin URL)

Figura 181. Nuevo resultado de inyeccion01.php


Podemos ver en la imagen anterior que se enva a la pgina una variable p
con el nmero de registro con el que inicia la pgina que se va a mostrar.
Ahora aprovecharemos esta variable para inyectar algunas cadenas SQL
valindonos de la funcin urlencode() para generar las cadenas.
Primero tendremos que hacer algunas suposiciones como por ejemplo que la
base de datos es MySQL y que se esta usando la orden LIMIT para la
paginacin de resultados y que el inicio es la variable p y que a continuacin
habr una coma y luego la cantidad de registros en la sentencia SQL en la
que ser reemplazado.
Parte de la cadena sera: LIMIT (la variable p),(cantidad) entonces para
terminar correctamente la cadena enviaremos junto con la variable p una
coma y un nmero que ser la cantidad de registros y luego insertaremos
UNION select * from usuario
Cadena a insertar: 0,2 union select * from usuario -Aplicando urlencode tenemos: 0%2C2+union+select+%2A+from+usuario+--+
Esta cadena que hemos generado ser el valor de p.
Veremos que sucede:
Oscar E Capuay Uceda

231

Seguridad Web

Figura 182. Tercer resultado de inyeccion01.php


Nos aparece un mensaje que nos dice que la sentencia SELECT tiene
diferente nmero de columnas (campos). Por ahora esto slo nos dice que
hemos podido inyectar una sentencia SELECT adicional pero nos queda
saber el nmero de campos de la consulta del listado y luego hacer coincidir
nuestro SELECT adicional con dicha cantidad.
Ahora supondremos que la cantidad de campos que vemos en el listado es
la cantidad del SELECT de la sentencia para el listado, ahora debemos
probar agregando campos al SELECT inyectado.
Agregaremos un campo al select inyectado.
Cadena a insertar: 0,2 union select *,1 from usuario -Aplicando urlencode: 0%2C2+union+select+%2A%2C1+from+usuario+--+
La cadena URL sera:

Figura 183. URL con inyeccin SQL


Ahora tenemos:

Figura 184. Resultado de la inyeccin SQL


Podemos decir que el nmero de campos coincidi y adems el nombre de
la tabla.
Sabiendo ahora lo que puede ocurrir, debemos prevenir este tipo de ataque
utilizando una funcin que se encargue de anular cualquier cadena que
Oscar E Capuay Uceda

232

Seguridad Web
pretenda inyectar SQL. Para el caso anterior debemos analizar y verificar
que el valor de la variable p sea un nmero obligatoriamente, entonces
aadimos la lnea:
if(!is_numeric($_GET[p])) $_GET[p]=0;
is_numeric es una funcin que devuelve TRUE si el valor de la variable es
numrico.
En caso que no sea numrico le asignamos CERO, segn la lnea de cdigo
anterior.
inyeccion02.php
<?php
include "mysqli-conexion.php"; //incluimos la conexion
$cantidad=2; //numero de registros por pagina
//verificamos si existe la variable
if(!isset($_GET[p])) $_GET[p]=0;
//hallamos el total de registros
$sql="select * from persona";
$rspersona=$mysqli->query($sql) or die($mysqli->error);
$nr=$rspersona->num_rows;
//verificamos si es p tiene valor numrico
if(!is_numeric($_GET[p])) $_GET[p]=0;
//paginacin de resultados
$sql="select idpersona,nombres,apellidos from persona limit " . $_GET[p] .
",$cantidad";
$rspersona=$mysqli->query($sql) or die($mysqli->error);
?>
<table>
<tr>
<th>Id</th>
<th>Nombres</th>
<th>Apellidos</th>
<th>Editar</th>
<th>Eliminar</th>
</tr>
<?php
//mostrar los registros
while($registro=$rspersona->fetch_object()) {
?>
<tr>
<td><?php echo "$registro->idpersona"?></td>
<td><?php echo "$registro->nombres"?></td>
Oscar E Capuay Uceda

233

Seguridad Web
<td><?php echo "$registro->apellidos"?></td>
<td><a
href="mysqli-editar.php?idpersona=<?php
>idpersona"?>">editar</a></td>
<td><a
href="mysqli-eliminar.php?idpersona=<?php
>idpersona"?>">eliminar</a></td>
</tr>

echo
echo

"$registro"$registro-

<?php
}
?>
<tr><td colspan="5">P&aacute;gina:
<?php
for($i=1;$i<=ceil($nr/$cantidad);$i++)
{
$inicio=$cantidad*($i-1);
echo "<a href='?p=$inicio'>$i</a> ";
}
?></td></tr>
</table>
<br>
<a href="formulario08.html">Agregar Registro</a>
<?php
$rspersona->close(); //cerramos resultado de la consulta
$mysqli->close(); //cerramos la conexin
?>
Con esta modificacin ejecutaremos la misma URL:

Figura 185. Evitando la inyeccin SQL


Resultado Web:

Figura 186. Resultado sin inyeccin realizada


Podemos ver ahora que la inyeccin SQL se evit exitosamente.
Pero los listados no solamente pueden ser utilizados para la Inyeccin SQL
sino que los formularios de acceso o logeo de usuarios quiz sean los ms
propensos a estos ataques. Para ver este caso ms de cerca primero
debemos tener tabla usuario, para este ejemplo consideremos dos campos
Oscar E Capuay Uceda

234

Seguridad Web
para esta tabla: login (nombre del usuario) y clave (password del usuario) y
luego registramos algunos registros.

Figura 187. Tabla usuario


Ahora haremos un formulario para el acceso de usuarios.
formulario09.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Acceso al sistema</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="inyeccion03.php">
<table width="50%" border="0" align="center">
<tr>
<th colspan="2">Acceso al sistema</th>
</tr>
<tr>
<td>Usuario</td>
<td><input name="usuario" type="text" id="usuario" maxlength="20"
/></td>
</tr>
<tr>
<td>Password</td>
<td><input name="passw" type="password" id="passw" maxlength="40"
/></td>
</tr>
<tr>
<th colspan="2"><input name="Submit" type="submit" class="boton"
value="Entrar" />
</th>
</tr>
</table>
</form>
</body>
</html>

Oscar E Capuay Uceda

235

Seguridad Web
Resultado Web:

Figura 188. Resultado de formulario09.html


El formulario anterior enva los datos a una pgina llamada inyeccion03.php.
Veamos ahora el archivo inyeccion03.php quien se encargar de controlar el
acceso de los usuarios.
inyeccion03.php
<?php
$sql="SELECT * from usuario WHERE login='" . $_POST[usuario] . "' and
clave='" . $_POST[passw] . "'";
//imprimir sentencia SQL
echo $sql;
?>
Con el script anterior imprimiremos la sentencia SQL que se crea cuando
enviamos los datos del formulario. Escribiremos dos datos de ejemplo y los
enviaremos:

Figura 189. Resultado de inyeccion03.php


La cadena resultante es la concatenacin de la sentencia SQL con los datos
escritos en el formulario (user, passuser). Pero ahora veamos lo que se
puede hacer para evitar un control correcto de los usuarios.
Analicemos la siguiente orden:

Oscar E Capuay Uceda

236

Seguridad Web
SELECT * from usuario WHERE login='loquesea' AND password= OR =
Si logramos generar una cadena como la anterior entonces no
necesitaremos tener un nombre de usuario correcto ni su respectiva clave
puesto que la condicin (WHERE) siempre resultar verdadera y por lo tanto
nos devolver todos los registros de la tabla usuario. Pero para llegar a
generar la ltima cadena debemos partir de la que suponemos se ha escrito
en el script, en este caso la que est en nuestro archivo inyeccion03.php.
Cadena inicial:
$sql="SELECT * from usuario WHERE login='" . $_POST[usuario] . "' and
clave='" . $_POST[passw] . "'";
Ahora a $_POST[usuario] le podemos dar cualquier valor, en este caso:
loquesea y a $_POST[passw] le daremos el valor: ' OR ''=' , con estos
valores resultara:
SELECT * from usuario WHERE login='loquesea' AND password= OR =
Probemos esto en el navegador con nuestro formulario09.html

Figura 190. Logeo con inyeccin SQL


Podemos tener dos resultados segn la configuracin de las comillas
mgicas gpc (Get/Post/Cookie) de PHP:
Cuando magic_quotes se encuentra activo, todos los caracteres ' (comillasimple), " (comilla doble), \ (barra invertida) y NULs son escapados con una
barra invertida automticamente como se ve a continuacin y por lo tanto la
inyeccin SQL no tendra xito.

Figura 191. Nuevo resultado de inyeccion03.php

Oscar E Capuay Uceda

237

Seguridad Web
Pero si magic_quotes se encuentra inactivo tendremos el siguiente
resultado:

Figura 192. Tercer resultado de inyeccion03.php


En este resultado podemos ver que la inyeccin si se ejecutara
exitosamente y el atacante podra ingresar al sistema sin un nombre de
usuario ni password vlido.
Podemos utilizar la funcin: get_magic_quotes_gpc la cual devuelve 0 si las
comillas mgicas estn deshabilitadas, 1 de lo contrario para hacer la
verificacin en tiempo de ejecucin y la funcin addslashes.
Con el formulario 10 probaremos un nuevo script que utilice estas dos
ltimas funciones, el formulario 10 solo vara en el valor del atributo action
de la etiqueta form.
formulario10.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Acceso al sistema</title>
</head>
<body>
<form
id="form1"
name="form1"
method="post"
action="comillasmagicas.php">
<table width="50%" border="0" align="center">
<tr> <th colspan="2">Acceso al sistema</th> </tr>
<tr>
<td>Usuario</td> <td><input name="usuario" type="text" id="usuario"
maxlength="20" /></td>
</tr>
<tr>
<td>Password</td>
<td><input
name="passw"
type="password"
id="passw" maxlength="40" /></td>
</tr>
<tr>
<th colspan="2"><input name="Submit" type="submit" class="boton"
value="Entrar" />
</th>
Oscar E Capuay Uceda

238

Seguridad Web
</tr>
</table>
</form>
</body>
</html>
Una vez cargado el formulario, ingresamos los datos de prueba.
Resultado Web:

Figura 193. Resultado de formulario10.html


Ejemplo 111:

get_magic_quotes_gpc y addslashes

comillas-magicas.php
<?php
if (!get_magic_quotes_gpc()) {
$password = addslashes($_POST['passw']);
} else {
$password = $_POST['passw'];
}
$sql="SELECT * from usuario WHERE login='" . $_POST[usuario] . "' and
clave='" . $password . "'";
//imprimir sentencia SQL
echo $sql;
?>
Veamos ahora el resultado:

Figura 194. Resultado de comillas-magicas.php

Oscar E Capuay Uceda

239

Seguridad Web
Podemos notar que se le agrega un \ (slash) a cada comilla, sin importar la
configuracin de las comillas mgicas, el script anterior no ayudara a evitar
la inyeccin SQL.
Con este script mejoramos el control del acceso a usuarios, pero cabe
resaltar una funcin creada para evitar este tipo de inyecciones SQL en
servidores MySQL, llamada: mysqli_real_escape_string (programacin
orientada a objetos) o mysql_real_escape_string (programacin
procedimental). Veamos un ejemplo con estilo orientado a objetos:
Ejemplo 112:

mysqli_real_escape_string

formulario11.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Acceso al sistema</title>
</head>
<body>
<form id="form1" name="form1" method="post" action="inyeccion04.php">
<table width="50%" border="0" align="center">
<tr> <th colspan="2">Acceso al sistema</th></tr>
<tr>
<td>Usuario</td> <td><input name="usuario" type="text" id="usuario"
maxlength="20" /></td>
</tr>
<tr>
<td>Password</td>
<td><input
name="passw"
type="password"
id="passw" maxlength="40" /></td>
</tr>
<tr>
<th
colspan="2"><input
name="Submit"
type="submit"
class="boton" value="Entrar" /> </th> </tr>
</table>
</form>
</body>
</html>
inyeccion04.php
<?php
//incluimos la conexion
include "mysqli-conexion.php";
$usuario =$mysqli->real_escape_string($_POST['usuario']);
$password=$mysqli->real_escape_string($_POST['passw']);
$sql="SELECT
*
from
usuario
WHERE
login='$usuario'
clave='$password'";
//imprimir sentencia SQL
Oscar E Capuay Uceda

and

240

Seguridad Web
echo $sql;
?>
Resultado Web:

Figura 195. Resultado de inyeccion04.php


Notamos que el control de la inyeccin SQL result exitoso con la funcin o
mtodo real_escape_string el cual protege de caracteres especiales en una
cadena para ser usada en una sentencia SQL, tomando en cuenta el
conjunto de caracteres para la conexin.

Oscar E Capuay Uceda

241

Seguridad Web

Sesiones
Las sesiones en PHP son un mecanismo para preservar datos a lo largo de
varios accesos lo que permite construir aplicaciones Web ms
personalizadas.
A cada visitante que accede a su Web se le asigna un identificador nico,
llamado "session id" (identificador de sesin). ste se almacena en una
cookie por parte del usuario o se propaga en la URL.
Las Cookies sirven para almacenar datos en el navegador del usuario. Se
pueden poner cookies usando la funcin setcookie(). Las Cookies son parte
de la cabecera HTTP, por tanto la funcin setcookie() debe ser llamada
antes de que se produzca cualquier salida al navegador.
El soporte de las sesiones le permite registrar un nmero arbitrario de
variables que se conservarn en las siguientes peticiones. Cuando un
visitante acceda a su Web, PHP comprobar automticamente (si
session.auto_start est puesto a 1) o cuando usted lo especifique (de forma
explcita mediante session_start() o implcita a travs de session_register())
si se le ha enviado un "session id" especfico con su peticin, en cuyo caso
se recrean las variables que se haban guardado anteriormente.
Todas las variables registradas son almacenadas tras finalizar la peticin.
Las variables que estn indefinidas se marcan como no definidas. En los
subsiguientes accesos, no estarn definidas por el mdulo de sesiones a
menos que el usuario las defina ms tarde.
Las opciones de configuracin track_vars y register_globals influyen
notablemente en la forma en que las variables de la sesin se almacenan y
restauran. A partir de PHP 4.0.3, track_vars siempre est activado. A partir
de PHP 4.1.0, $_SESSION est disponible como variable global, al igual que
$_POST,
$_GET,
$_REQUEST
y
dems.
Al
contrario
que
$HTTP_SESSION_VARS, $_SESSION siempre es global. Por tanto, no se
debe usar global para $_SESSION.
Si track_vars est activado y register_globals est desactivado, slo los
miembros del vector asociativo global $HTTP_SESSION_VARS pueden ser
registrados como variables de la sesin. Las variables restauradas de la
sesin slo estarn disponibles en el vector $HTTP_SESSION_VARS.
Se recomienda usar $_SESSION (o $HTTP_SESSION_VARS con PHP
4.0.6 o inferior) por seguridad y para hacer el cdigo ms legible. Con
$_SESSION o $HTTP_SESSION_VARS, no es necesario usar las funciones
session_register() / session_unregister() / session_is_registered(). Los
usuarios pueden acceder a una variable de la sesin como si se tratase de
una variable normal.
Si register_globals est activado, todas las variables globales pueden ser
registradas como variables de la sesin, y las variables de la sesin sern
restauradas a sus correspondientes variables globales. Como PHP debe
Oscar E Capuay Uceda

242

Seguridad Web
saber qu variables globales estn registradas como variables de la sesin,
los usuarios deben registrar las variables con la funcin session_register(),
mientras que con $HTTP_SESSION_VARS/$_SESSION no es necesario
usar session_register().
Si est usando $HTTP_SESSION_VARS/$_SESSION y desactiva
register_globals, no use session_register(), session_is_registered() ni
session_unregister().
Se recomienda desactivar register_globals por motivos de seguridad y
rendimiento.
Ejemplo 113:

Ingreso de un usuario a la aplicacin

ingreso01.php
<form action="verifica01.php" method="post">
<table
width="70%"
border="0"
cellspacing="1"
align="center">
<caption>
Acceso al sistema
</caption>

cellpadding="2"

<tr>
<td>Usuario</td>
<td><input type="text" name="txtusuario" id="txtusuario" maxlength="20">
</td>
</tr>
<tr>
<td>Password</td>
<td><input
name="txtclave"
type="password"
id="txtclave"
maxlength="50"></td>
</tr>
<?php
if($_GET['error']==1) {
?>
<tr><td colspan="2">Datos Incorrectos</td></tr>
<?php } ?>
<tr>
<th
colspan="2"><input
type="submit"
name="Submit"
value="Entrar"></th>
</tr>
</table>
</form>
<?php
echo "Su direcci&oacute;n IP es: ".$_SERVER['REMOTE_ADDR'];
?>
<br>
<?php
echo "Navegador: ".$_SERVER['HTTP_USER_AGENT'];
?>
Oscar E Capuay Uceda

243

Seguridad Web
<br>
<?php
echo "Idioma: ".$_SERVER['HTTP_ACCEPT_LANGUAGE'];
?>
Resultado Web:

Figura 196. Resultado de ingreso01.php

Ejemplo 114:

Verifica datos del usuario

verifica01.php
<?php
include "mysqli-conexion.php"; //incluimos la conexion
//Proteger de caracteres especiales a la sentencia SQL
$usuario =$mysqli->real_escape_string($_POST['txtusuario']);
$clave =$mysqli->real_escape_string($_POST['txtclave']);
//ciframos la clave escrita por el usuario para compararla en la BD
$clave=md5($clave);
//sentencia sql
$sql="select * from usuario where login='$usuario' and clave='$clave'";
//ejecutamos la consulta
$rsusuario=$mysqli->query($sql) or die($mysqli->error);
if($rsusuario->num_rows==1)
{
//datos correctos
$reg=$rsusuario->fetch_object();
session_start();
$_SESSION['idusuario']=$reg->idusuario;
$_SESSION['usuario']=$reg->usuario;

Oscar E Capuay Uceda

244

Seguridad Web
$_SESSION['tipo']=$reg->tipo;
} else header("location: ingreso01.php?error=1");
?>
Probamos con datos incorrectos.

Figura 197. Ingreso01.php con datos incorrectos

Figura 198. Logeo incorrecto


La aplicacin nos devuelve un mensaje de Datos Incorrectos.

Oscar E Capuay Uceda

245

Seguridad Web

Autentificacin HTTP con PHP


Las caractersticas de autentificacin HTTP en PHP solo estn disponibles
cuando se est ejecutando como un mdulo en Apache y hasta ahora no lo
estn en la versin CGI. En un script PHP como mdulo de Apache, se
puede usar la funcin header() para enviar un mensaje de "Autentificacin
requerida" al navegador cliente haciendo que muestre una ventana de
entrada emergente con nombre de usuario y contrasea. Una vez que el
usuario ha rellenado el nombre y la contrasea, la URL que contiene el script
PHP ser llamada de nuevo con las variables predefinidas
PHP_AUTH_USER, PHP_AUTH_PW, y AUTH_TYPE asignadas con el
nombre de usuario, la contrasea y el tipo de autentificacin
respectivamente. Estas variables predefinidas se pueden encontrar en las
matrices $_SERVER y $HTTP_SERVER_VARS. Slo autentificacin
"Bsica" est soportada en este momento.
Ejemplo 115:

Autenticacin HTTP

auth01.php
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="Sistema Web"');
header('HTTP/1.0 401 Unauthorized');
echo 'Operaci&oacute;n cancelada';
exit;
} else {
echo "<p>Bienvenido {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>Acceso al sistema con password:
{$_SERVER['PHP_AUTH_PW']}.</p>";
}
?>
Resultado Web:

Figura 199. Autenticacin http con PHP

Oscar E Capuay Uceda

246

Seguridad Web
Si cancelamos la operacin tenemos el siguiente resultado en el navegador,
segn lo establecido en el cdigo.

Figura 200. Resultado de auth01.php


Si ingresamos datos y presionamos Aceptar tendremos:

Figura 201. Autenticacin con datos correctos

Figura 202. Resultado de auth01.php con datos correctos

Oscar E Capuay Uceda

247

Seguridad Web

Login
Ahora que ya tenemos el script de autenticacin de usuarios,
desarrollaremos el script para verificar el nombre de usuario y contrasea en
la base de datos. Utilizaremos una tabla usuario, con campos que contengan
el nombre y contrasea del usuario.

Figura 203. Tabla usuario


Script sql:
CREATE TABLE `usuario` (
`idusuario` int(11) NOT NULL auto_increment,
`login` varchar(10) collate latin1_spanish_ci NOT NULL,
`clave` varchar(32) collate latin1_spanish_ci NOT NULL,
PRIMARY KEY (`idusuario`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
COLLATE=latin1_spanish_ci AUTO_INCREMENT=1;

Una vez implementada la base de datos ingresaremos algunos registros


para los casos de prueba necesarios para probar el script que
desarrollaremos.

Figura 204. registro de un usuario

Oscar E Capuay Uceda

248

Seguridad Web
Como podemos observar en la figura anterior, para ingresar un nuevo
registro debemos aplicar la funcin md5 a la contrasea del usuario.
Ahora desarrollaremos el script de logeo de usuarios. Para ello podremos
usar como mecanismo de ingreso de datos el script de autenticacin
desarrollado en el tema anterior o usar un formulario HTML como el
siguiente:
Ejemplo 116:

Formulario para el logeo de usuarios

entrar.php
<HTML>
<HEAD>
<TITLE>Login</TITLE>
</HEAD>
<BODY>
<form name="form1" action="logeo.php" method="post">
<table align="center" width="50%">
<tr><th colspan="2">Ingreso al sistema</th></tr>
<tr><td>Usuario</td>
<td><input type="text" name="txtusuario"></td></tr>
<tr><td>Password</td>
<td><input type="password" name="txtclave"></td></tr>
<tr><th colspan="2"><input type="submit" value="Entrar"></th></tr>
</table>
<?php
if($_GET['error']==1) echo "Datos Incorrectos";
if($_GET['error']==2) echo "Debe logearse";
?>
</form>
</BODY>
</HTML>
Resultado Web:

Figura 205. Resultado de entrar.php

Oscar E Capuay Uceda

249

Seguridad Web
Ejemplo 117:

Logeo de usuarios

logeo.php
<?php
include "mysqli-conexion.php";
$usuario=$mysqli->real_escape_string($_POST['txtusuario']);
$clave=md5($_POST['txtclave']);
$sql="select * from usuario where login='$usuario' and clave='$clave'";
$rsusuario=$mysqli->query($sql) or die($mysqli->error);
if($rsusuario->num_rows==1) {
$registro=$rsusuario->fetch_object();
session_start();
$_SESSION['sidusuario']= $registro->idusuario;
$_SESSION['susuario']= $usuario;
header("location: mysqli-listado-logeado.php");
}
else header("location: entrar.php?error=1");
?>
En este script utilizamos el mtodo real_escape_string. Esta funcin es
usada para crear una cadena SQL sin inyeccin SQL. Los caracteres
codificados son NULL (ASCII 0), \n, \r, \, ', ", y Control-Z. Adems usamos la
funcin md5 para cifrar la clave escrita en el formulario y compararla con la
cadena cifrada guardada en la base de datos.
Si el nmero de registros es 1 (uno), significa que los datos son correctos y
pertenecen a uno y solo un usuario (no pueden haber varios usuarios con el
mismo nombre). Por lo que debemos iniciar una sesin utilizando la funcin
session_start. El apoyo que PHP proporciona para las sesiones consiste en
una forma de conservar ciertos datos a lo largo de los subsiguientes
accesos, lo cual le permite construir aplicaciones ms personalizadas e
incrementar el atractivo de su sitio Web.
Utilizaremos tambin, al array $_SESSION[] para registrar las variables de
sesin de nuestra aplicacin, en este caso especfico, para registrar el
identificador del usuario (idusuario) y su nombre de usuario (usuario).
A partir de PHP 4.1.0, $_SESSION est disponible como variable global, al
igual que $_POST, $_GET, $_REQUEST y dems. Al contrario que
$HTTP_SESSION_VARS, $_SESSION siempre es global. Por tanto, no se
debe usar global para $_SESSION.
Cuando los datos ingresados son incorrectos, retornar a la pgina inicial, de
lo contrario el script redirecciona el navegador hacia el listado de personas
(archivo: mysqli-listado.php), el cual, tiene dos nuevas lneas de cdigo con
respecto al ejemplo 76.

Oscar E Capuay Uceda

250

Seguridad Web
Resultado Web cuando los datos son incorrectos

Figura 206. Resultado de entrar.php con datos incorrectos


Si alguien quisiera ingresar a nuestro listado sin logearse podra escribir
directamente la direccin de la pgina y lo podra hacer, pero ahora que
hemos iniciado una sesin y hemos registrado algunas variables podremos
controlar dicha accin y obligar a los usuarios a logearse antes de acceder a
ciertas pginas. Veamos a continuacin cul sera la lgica del script.
Ejemplo 118:

Verifica si el usuario se ha logeado

mysqli-listado-logeado.php
<?php
session_start();
if(!isset($_SESSION['sidusuario'])) header("location: entrar.php?error=2");
include "mysqli-conexion.php"; //incluimos la conexion
//consulta sql
$sql="select * from persona";
//ejecucion de la sentencia sql
$rspersona=$mysqli->query($sql) or die($mysqli->error);
echo "Usuario:" . $_SESSION['susuario'];
?>
<table>
<tr>
<th>Id</th>
<th>Nombres</th>
<th>Apellidos</th>
<th>Editar</th>
<th>Eliminar</th>
</tr>
<?php
//mostrar los registros
while($registro=$rspersona->fetch_object())
{ ?>
<tr>
<td><?php echo "$registro->idpersona"?></td>
<td><?php echo "$registro->nombres"?></td>
<td><?php echo "$registro->apellidos"?></td>
Oscar E Capuay Uceda

251

Seguridad Web
<td><a
href="mysqli-editar.php?idpersona=<?php
echo
>idpersona"?>">editar</a></td>
<td><a
href="mysqli-eliminar.php?idpersona=<?php
echo
>idpersona"?>">eliminar</a></td>
</tr>
<?php
}
$rspersona->close(); //cerramos resultado de la consulta
$mysqli->close(); //cerr=amos la conexin
?>
</table>
<br>
<a href="formulario08.html">Agregar Registro</a>

"$registro"$registro-

Resultado Web:

Figura 207. Resultado de mysqli-listadologeado.php


En este script al iniciar la sesin (session_start()) podremos acceder a todas
las variables de sesin y eso nos permitir verificar si el usuario se ha
logeado y lo haremos comprobando si existe la variable de sesin que se
registra en el archivo logeo.php cuando los datos son correctos.
En adelante, a toda pgina en la que el usuario haya tenido que identificarse
se le debe insertar las primeras lneas escritas en el script.
session_start();
if(!isset($_SESSION['sidusuario'])) header("location: entrar.php?error=2");

Oscar E Capuay Uceda

252

Seguridad Web

CAPTCHA
Este nombre proviene del acrnimo de: Completely Automatic Public Turing
Test to Tell Computers and Humans Apart, que traducido al espaol
significa: Prueba de Turing pblica y automtica para diferenciar a mquinas
y humanos.
Se trata de una prueba desafo-respuesta utilizada en computacin para
determinar cundo el usuario es o no humano. El trmino se empez a
utilizar en el ao 2000 por Luis von Ahn, Manuel Blum y Nicholas J. Hopper
de la Carnegie Mellon University, y John Langford de IBM.
La tpica prueba consiste en que el usuario introduzca un conjunto de
caracteres que se muestran en una imagen distorsionada que aparece en
pantalla. Se supone que una mquina no es capaz de comprender e
introducir la secuencia de forma correcta por lo que solamente el humano
podra hacerlo.
Como el test es controlado por una mquina en lugar de un humano como
en la Prueba de Turing, tambin se denomina Prueba de Turing Inversa.
Los CAPTCHAs son utilizados para evitar que robots, tambin llamados
spambots, puedan utilizar ciertos servicios. Por ejemplo, para que no puedan
participar en encuestas, registrarse para usar cuentas de correo electrnico
(o su uso para envo de correo basura) o, ms recientemente, para evitar
que correo basura pueda ser enviado por un robot (el remitente debe pasar
el test antes de que se entregue al destinatario). [8]
El sistema CAPTCHA tiene las siguientes caractersticas por definicin:
Son completamente automatizados, es decir, no es necesario ningn
tipo de mantenimiento / intervencin humana para su realizacin.
Esto supone grandes beneficios en cuanto a fiabilidad y coste.
El algoritmo utilizado es pblico. De esta forma la ruptura de un
captcha pasa a ser un problema de inteligencia artificial y no la
ruptura de un algoritmo secreto.
A continuacin construiremos con PHP un CAPTCHA.
El primer paso es disear y programar el formulario en el que aparecer
nuestro CAPTCHA:
Ejemplo 119:

Formulario CAPTCHA

form-catcha.php
<?php
session_start();
if(isset($_POST["palabra"])) {
if($_POST["palabra"] == $_SESSION["oculto"])
die("Felicidades! Ha ledo correctamente la palabra.");
else
Oscar E Capuay Uceda

253

Seguridad Web
die("No has adivinado la palabra. Prueba otra vez");
} else {
?>
<form method="post" action="">
<img src="capu-captcha.php">
<input type="text" name="palabra">
<input type="submit" value="Comprobar">
</form>
<?php
}
?>

Ejemplo 120:

Generador CAPTCHA

capu-captcha.php
<?php
session_start();
// estas cabeceras evitan que se almacene la imagen en el cach
header ("Expires: Sat, 12 Jul 2008 09:00:00 GMT");
header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header ("Cache-Control: no-store, no-cache, must-revalidate");
header ("Cache-Control: post-check=0, pre-check=0", false);
header ("Pragma: no-cache");
// creamos la imagen con el tamao determinado
$imagen = imagecreate(250, 100);
// elegimos los colores para el fondo y el texto
$rojo = mt_rand(150,200);
$verde = mt_rand(150,200);
$azul = mt_rand(200,250);
$rojo_fondo = mt_rand(80,120);
$verde_fondo = mt_rand(80,120);
$azul_fondo = mt_rand(80,200);
$rojo_basura = $rojo+55;
$verde_basura = $verde+55;
$azul_basura = $azul+5;
$color_texto = imagecolorallocate($imagen,$rojo,$verde,$azul);
$color_fondo =
imagecolorallocate($imagen,$rojo_fondo,$verde_fondo,$azul_fondo);
$color_basura =
imagecolorallocate($imagen,$rojo_basura,$verde_basura,$azul_basura);
//aplicamos el color de fondo
imagefill($imagen,0, 0, $color_fondo);
// construimos la palabra
$caracteres =
"ABCDEFGHJKMNPRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";
Oscar E Capuay Uceda

254

Seguridad Web
//indicar la cantidad de caracteres que tendr la palabra del CAPTCHA
$cantidad=6;
for($i=1;$i<=$cantidad;$i++) {
$pos = mt_rand(0,strlen($caracteres)-1);
$palabra.= substr($caracteres,$pos,1);
}
// comprobamos la existencia de la funcin ImageTTFText()
$fontsList = array(
"./fonts/VeraMoBd.ttf",
"./fonts/VeraMoBI.ttf",
"./fonts/VeraMono.ttf",
"./fonts/VeraMoIt.ttf"
);
$randFontNo = mt_rand(0, sizeof($fontsList)-1);
$randFontPath = realpath($fontsList[ $randFontNo ]);
// al azar las seales al fondo del respectivo texto ImageTTFText
for($i=1;$i<20;$i++){
$x
= mt_rand(0, 250); // pos x
$y
= mt_rand(0, 100); // pos y
$car = chr(mt_rand(45, 250)); //caracter aleatorio
$angulo = mt_rand(3,180);
imagettftext($imagen, 12, $angulo, $x, $y, $color_basura,
$randFontPath, $car);
}
// imprimir la palabra
$x = mt_rand(10,120);
$y = mt_rand(40,65);
imagettftext($imagen, 28, mt_rand(-10,10), $x, $y, $color_texto,
$randFontPath, $palabra);
//ensuciamos la imagen con lneas
for($i=1;$i<60;$i++){
$x = mt_rand(0, 250);
$y = mt_rand(0, 100);
imageline($imagen, $x, $y, $x+mt_rand(-40,40), $y+mt_rand(40,40), $color_basura);
}
// enviamos mediante la sesin la palabra elegida
$_SESSION["oculto"] = $palabra;
// enviamos la cabecera correspondiente al navegador y luego la imagen
header("Content-type: image/png");
imagepng($imagen);
// eliminamos la imagen
imagedestroy($imagen);
?>

Oscar E Capuay Uceda

255

Seguridad Web
Resultados Web:
Podemos ver a continuacin varios ejemplos de los CAPTCHAs generados.

Figura 208. Ejemplo1 de CAPTCHA

Figura 209. Ejemplo2 de CAPTCHA

Figura 210. Ejemplo3 de CAPTCHA

Oscar E Capuay Uceda

256

También podría gustarte