> Manuales > Taller de PHP

Nuestro objetivo es construir un carro de compras muy simple, para ver su funcionamiento. Luego, cada uno de ustedes podrá adaptarlo a sus necesidades y/o mejorarlo para que sea más cómodo para el usuario.

Pueden ver el ejemplo en marcha de lo que vamos a hacer aquí.
Antes de empezar veremos, de manera resumida, para qué se utilizan las sesiones:
Las sesiones nos permiten registrar un número arbitrario de variables que se conservan durante toda la visita de un usuario a una página web. Dichas variables pueden ser diferentes para cada usuario, ya que están referenciadas por un identificador único que se le asigna a cada visitante. En otras palabras, una sesión es una manera de almacenar variables de manera temporal, semejante a una cookie, pero con ciertas diferencias: las cookies se almacenan en la PC del usuario y pueden desactivarse; las sesiones, en cambio, se almacenan temporalmente en el servidor, en un fichero que se crea en el momento en que almacenamos la variable. Sabiendo esto, ya estamos en condiciones de entender cómo va a funcionar nuestro carro de compras.

Primero crearemos en mysql una tabla para nuestro catálogo de artículos:

create table catalogo (id int not null auto_increment primary key,producto varchar(100),precio decimal(9,2))

También vamos a necesitar algunas imágenes para ayudar visualmente al usuario que va a utilizar nuestro carrito (en el ejemplo vamos a utilizar estas, luego cada uno las reemplaza por las que quiera):

Imagen de producto no agregado al carrito:
productonoagregado.gif

Imagen de producto agregado:
productoagregado.gif

Botón para eliminar un producto del carrito:
trash.gif

Botón para actualizar las cantidades de un producto agregado:
actualizar.gif

Botón para continuar la selección de artículos:
continuar.gif

Botón para ver el contenido del carrito:
vercarrito.gif

Con estos elementos, podemos crear el archivo agregacar.php, que nos servirá para introducir productos dentro del carro (y para modificar sus cantidades) y que contendrá el siguiente código:

<?php
session_start();
//con session_start() creamos la sesión
//si no existe o la retomamos si ya ha
//sido creada
extract($_REQUEST);
//la función extract toma las claves
//de una matriz asoiativa y las
//convierte en nombres de variable,
//asignándoles a esas variables
//valores iguales a los que tenía
//asociados en la matriz. Es decir,
//convierte a $_GET['id'] en $id,
//sin que tengamos que tomarnos el
//trabajo de escribir
//$id=$_GET['id'];
mysql_connect("localhost","usuario","password");
mysql_select_db("db");
//incluímos la conexión a nuestra
//base de datos
if(!isset($cantidad)){$cantidad=1;}
//Como también vamos a usar este
//archivo para actualizar las
//cantidades, hacemos que cuando
//la misma no esté indicada sea
//igual a 1
$qry=mysql_query("select * from catalogo where
id='".$id."'");
$row=mysql_fetch_array($qry);
//Si ya hemos introducido algún
//producto en el carro lo
//tendremos guardado temporalmente
//en el array superglobal
//$_SESSION['carro'], de manera
//que rescatamos los valores de
//dicho array y se los asignamos
//a la variable $carro, previa
//comprobación con isset de que
//$_SESSION['carro'] ya haya sido
//definida
if(isset($_SESSION['carro']))
$carro=$_SESSION['carro'];
//Ahora introducimos el nuevo
//producto en la matriz $carro,
//utilizando como índice el id
//del producto en cuestión,
//encriptado con md5.
//Utilizamos md5 porque genera
//un valor alfanumérico que luego,
//cuando busquemos un producto
//en particular dentro de la
//matriz, no podrá ser confundido
//con la posición que ocupa dentro
//de dicha matriz, como podría
//ocurrir si fuera sólo numérico.
//Cabe aclarar que si el producto
//ya había sido agregado antes,
//los nuevos valores que le
//asignemos reemplazarán a los
//viejos.
//Al mismo tiempo, y no porque
//sea estrictamente necesario
//sino a modo de ejemplo,
//guardamos más de un valor en
//la variable $carro, valiéndonos
//de nuevo de la herramienta array.
$carro[md5($id)]=array('identificador'=>md5($id),
'cantidad'=>$cantidad,'producto'=>$row['producto'],
'precio'=>$row['precio'],'id'=>$id);
//Ahora dentro de la sesión
//($_SESSION['carro']) tenemos
//sólo los valores que teníamos
//(si es que teníamos alguno)
//antes de ingresar a esta página
//y en la variable $carro tenemos
//esos mismos valores más el que
//acabamos de sumar. De manera que
//tenemos que actualizar (reemplazar)
//la variable de sesión por la
//variable $carro.
$_SESSION['carro']=$carro;
//Y volvemos a nuestro catálogo de
//artículos. La cadena SID representa
//al identificador de la sesión, que,
//dependiendo de la configuración del
//servidor y de si el usuario tiene
//o no activadas las cookies puede
//no ser necesario pasarla por la url.
//Pero para que nuestro carro funcione,
//independientemente de esos factores,
//conviene escribirla siempre.
header("Location:catalogo.php?".SID);
?>


Luego creamos el archivo borracar.php, que nos permitirá eliminar artículos que hayamos ingresado:

<?php
session_start();
//con session_start()
//creamos la sesión si
//no existe o la retomamos
//si ya ha sido creada
extract($_GET);
//Como antes, usamos
//extract() por comodidad,
//pero podemos no hacerlo
//tranquilamente
$carro=$_SESSION['carro'];
//Asignamos a la variable
//$carro los valores
//guardados en la sessión
unset($carro[md5($id)]);
//la función unset borra
//el elemento de un array
//que le pasemos por
//parámetro. En este caso
//la usamos para borrar el
//elemento cuyo id le pasemos
//a la página por la url
$_SESSION['carro']=$carro;
//Finalmente, actualizamos
//la sessión, como hicimos
//cuando agregamos un producto
//y volvemos al catálogo
header("Location:catalogo.php?".SID);
?>


Luego creamos nuestro catálogo de productos, el archivo catalogo.php:

<?php
ob_start("ob_gzhandler");
//Las funciones ob_start y
//ob_end_flush te permiten
//escojer en qué momento
//enviar el resultado de un
//script al navegador. Si
//no las utilizamos estamos
//obligados a que nuestra
//primera línea de código
//sea session_start() u
//obtendremos un error
session_start();
//conectamos a la base de
//datos
mysql_connect("localhost","usuario","password");
mysql_select_db("db");
//rescatamos los valores
//guardados en la variable de
//sesión (si es que hay alguno,
// cosa que comprobamos con isset)
//y los asignamos a $carro.
//Si no existen valores, ponemos a false
//el valor de $carro
if(isset($_SESSION['carro']))
$carro=$_SESSION['carro'];else $carro=false;
//y hacemos la consulta
$qry=mysql_query("select * from catalogo order by producto asc");
?>
<html>
<head>
<title>CATÁLOGO</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
.catalogo {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9px;
color: #333333;
}
-->
</style>
</head>
<body>
<table width="272" align="center" cellpadding="0" cellspacing="0" style="border: 1px solid #000000;">
<tr valign="middle" bordercolor="#FFFFFF" bgcolor="#DFDFDF" class="catalogo">
<td width="170"><strong>Producto</strong></td>
<td width="77"><strong>Precio</strong></td>
<td width="25" align="right"><a href="vercarrito.php?<?php echo SID ?>" title="Ver el contenido del carrito">
<img src="vercarrito.gif" width="25" height="21" border="0"></a></td>
</tr>
<?php
//mostramos todos nuestros
//artículos, viendo si han
//sido agregados o no a nuestro
//carro de compra
while($row=mysql_fetch_assoc($qry)){
?>
<tr valign="middle" class="catalogo">
<td><?php echo $row['producto'] ?></td>
<td><?php echo $row['precio'] ?></td>
<td align="center">
<?php
if(!$carro || !isset($carro[md5($row['id'])]['identificador']) || $carro[md5($row['id'])]['identificador']!=md5($row['id'])){
//si el producto no ha sido
//agregado, mostramos la imagen
//de no agregado, linkeada
//a nuestra página de agregar
//producto y transmitíéndole a
//dicha página el id del artículo
//y el identificador de la sesión
?>
<a href="agregacar.php?<?php echo SID ?>&id=<?php echo $row['id']; ?>">
<img src="productonoagregado.gif" border="0" title="Agregar al Carrito"></a><?php }else
//en caso contrario mostramos la
//otra imagen linkeada., a la
//página que sirve para borrar el
//artículo del carro.
{?><a href="borracar.php?<?php echo SID ?>&id=<?php echo $row['id']; ?>">
<img src="productoagregado.gif" border="0" title="Quitar del Carrito"></a><?php } ?></td>
</tr><?php } ?>
</table>
</body>
</html>
<?php
ob_end_flush();
?>


Y por último el archivo en el que mostramos el contenido del carro, llamado vercarrito.php:

<?php
session_start();
//Iniciamos o retomamos la
//sesión
if(isset($_SESSION['carro']))
$carro=$_SESSION['carro'];else $carro=false;
//La asignamos a la variable
//$carro si existe o ponemos a false $carro
//en caso contrario
?>
<html>
<head>
<title>PRODUCTOS AGREGADOS AL CARRITO</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
.tit {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9px;
color: #FFFFFF;
}
.prod {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9px;
color: #333333;
}
h1 {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 20px;
color: #990000;
}
-->
</style>
</head>
<body>
<h1 align="center">Carrito</h1>
<?php
if($carro){
//si el carro no está vacío,
//mostramos los productos
?>
<table width="720" border="0" cellspacing="0" cellpadding="0" align="center">
<tr bgcolor="#333333" class="tit">
<td width="105">Producto</td>
<td width="207">Precio</td>
<td colspan="2" align="center">Cantidad de Unidades</td>
<td width="100" align="center">Borrar</td>
<td width="159" align="center">Actualizar</td>
</tr>
<?php
$color=array("#ffffff","#F0F0F0");
$contador=0;
//las 2 líneas anteriores
//sirven sólo para hacer
//una tabla con colores
//alternos
$suma=0;
//antes de recorrer todos
//los valores de la matriz
//$carro, ponemos a cero la
//variable $suma, en la que
//iremos sumando los subtotales
//del costo de cada item por la
//cantidad de unidades que se
//especifiquen
foreach($carro as $k => $v){
//recorremos la matriz que tiene
//todos los valores del carro,
//calculamos el subtotal y el
// total
$subto=$v['cantidad']*$v['precio'];
$suma=$suma+$subto;
$contador++;
//este es el contador que usamos
//para los colores alternos
?>
<form name="a<?php echo $v['identificador'] ?>" method="post" action="agregacar.php?<?php echo SID ?>" id="a<?php echo $v['identificador'] ?>">
<tr bgcolor="<?php echo $color[$contador%2]; ?>" class='prod'>
<td><?php echo $v['producto'] ?></td>
<td><?php echo $v['precio'] ?></td>
<td width="43" align="center"><?php echo $v['cantidad'] ?></td>
<td width="136" align="center">
<input name="cantidad" type="text" id="cantidad" value="<?php echo $v['cantidad'] ?>" size="8">
<input name="id" type="hidden" id="id" value="<?php echo $v['id'] ?>"> </td>
<td align="center"><a href="borracar.php?<?php echo SID ?>&id=<?php echo $v['id'] ?>"><img src="trash.gif" width="12" height="14" border="0"></a></td>
<td align="center">
<input name="imageField" type="image" src="actualizar.gif" width="20" height="20" border="0"></td>
</tr></form>
<?php
//por cada item creamos un
//formulario que submite a
//agregar producto y un link
//que permite eliminarlos
}
?>
</table>
<div align="center"><span class="prod">Total de Artículos: <?php echo count($carro);
//el total de items va a ser igual
//a la cantidad de elementos que
//tenga la matriz $carro, valor
//que obtenemos con la función
//count o con sizeof
?></span>
</div><br>
<div align="center"><span class="prod">Total: $<?php echo number_format($suma,2);
//mostramos el total de la variable
//$suma formateándola a 2 decimales
?></span>
</div><br>
<div align="center"><span class="prod">Continuar la selección de productos</span>
<a href="catalogo.php?<?php echo SID;?>">
<img src="continuar.gif" width="13" height="13" border="0"></a>
</div>
<?php }else{ ?>
<p align="center"> <span class="prod">No hay productos seleccionados</span>
<a href="catalogo.php?<?php echo SID;?>">
<img src="continuar.gif" width="13" height="13" border="0"></a>
<?php }?>
</p>
</body>
</html>


Y listo, ya tenemos nuestro carrito en funcionamiento.

Todos los archivos utilizados están disponibles para descargar gratuitamente desde el botón de descargas, ubicado en el lateral izquierdo de esta misma página.

Andrés Fernández

Manual