Bueno este es mi primer post y espero que les sea de buena utilidad.
A continuación veremos como se crea un carrito de compras usando PHP5, POO y MYSQL.
Al final del post se encontrará el link para descargar el código completo y la BD.
Primero que nada necesitaremos crearnos un par de tablas que vamos a trabajarlas.
Ahi la estructura de las tabla.(Las tablas la encontraran en el archivo adjunto de abajo.)
EMPEZEMOS:
1.Crearemos la clase Conexion: Conexion.class.php
<?php
class Conexion{
private $hilo; //Variable para retornar el valor de la conexion.
private $resultSet; //Variable para retornar el valor de la consulta.
//Función que se ejecutará ni bien se haya instanciado en objeto Conexión.
public function __construct($server = '127.0.0.1',
$username = 'root',
$password = '',
$database = 'carrito') {
//Nos conectamos la BD
$this->hilo = mysql_pconnect($server,$username,$password);
//Si en caso haya fallado la conexión a la BD mostramos un mensaje de error.
if(!$this->hilo){
die('No se pudo conectar a la Base de Datos:' . mysql_error());
}
//Si en caso no se ha podido acceder a la BD mostramos un mensaje de rror
if(!mysql_select_db($database,$this->hilo)){
die('No se pudo conectar a la BD '.$database.':'. mysql_error());
}
}
//Esta función nos permitirá ejecutar cualquier tipo de consulta Select, Insert, Update o Delete
public function ejecutar($sql){
$this->resultSet=mysql_query($sql); //Si sale bien.
if(!$this->resultSet){ //Si hay un error.
die('No se pudo realzizar la consulta:<br />'.$sql.'<br />'. mysql_error());
}
return $this->resultSet; //Retorna el valor obtenido de la consulta.
}
//La función desctructor se ejecutará una vez terminado todo el script y cerrará la conexión
public function __destruct() {
if(!$this->hilo)mysql_close($this->hilo);
}
}
?>
2. Pasamos a crear la clase: Producto.class.php
//Se le asignara los atributos correspondientes
<?php
class Producto{
//Atributos
public $codpro;
public $nompro;
public $prepro;
public $cantidad;
//Constructor se ejecutará una vez instanciado al Objeto(recibirá 3 parámetros codpro,nompro y prepro)
public function __construct($c,$n,$p) {
$this->codpro=$c;
$this->nompro=$n;
$this->prepro=$p;
$this->cantidad=1; //Se le asignara un valor por defecto 1.
}
//Metodo que nos permitirá calcular el precio Total por cada producto insertado al carrito
public function precioTotal(){
//Se aplica un formato para números con 2 decimales.
return number_format($this->prepro*$this->cantidad, 2, '.', '');
}
}
?>
3.Pasamos a crear la clase: Carrito.class.php
<?php
class Carrito{
public $codigo; //atributo codigo de carrito
public $productos; //atributo productos, contendra todo los productos seleccionados al carrito
function __construct($id) {
$this->codigo=$id;
$this->productos=array(); //instanciamos el atributo productos l ista para ser llenado de productos
}
//Indico el codigo y recupero un producto si es que existe en el carrito
public function obtenerProducto($codigo){
foreach($this->productos as $indice => $producto){
if($producto->codpro==(int)$codigo){
return $producto;
}
}
return null;
}
//Actualiza la cantidad de items para un mismo producto que ya existe en el carrito
//En caso existe el mismo producto que se quiera insertar al carrito la cantidad suma +1
public function actualizarCantidad($codigo,$cantidad){
foreach ($this->productos as $indice => $producto){
if($producto->codpro==(int)$codigo){
$producto->cantidad +=$cantidad;
}
}
}
//Agrego o actualizo su cantidad de un producto al carrito
public function agregarProducto($producto){
//Busco el producto si ya fue insertado
$yaIncluido = $this->obtenerProducto($producto->codpro); //Buscará si existe el producto
if($yaIncluido){
$this->actualizarCantidad($producto->codpro, 1); //Busco y actualizo el producto
}else{
$this->productos[]=$producto; //Agrego un nuevo producto al carrito
}
}
//Calcular el monto total de los productos
public function calcularMonto(){
$monto = 0;
foreach($this->productos as $indice => $producto){
$monto += $producto->precioTotal();
}
return number_format($monto, 2, '.', '');
}
//Nos permitirá calcular la cantidad total de productos insertados al carrito
public function calcularCantidad(){
$cantidad = 0;
foreach($this->productos as $indice => $producto){
$cantidad += $producto->cantidad;
}
return $cantidad;
}
//Calcular descuento segun cantidad total.
public function calcularDescuento(){
$cantidad = $this->calcularCantidad();
if($cantidad > 1000){
return 20;
}else if($cantidad > 100){
return 10;
}else if($cantidad > 3){
return 2;
}else
return 0;
}
//Calcular precio total, con el montoTotal y el descuento.
public function calcularPrecioTotal(){
$total=$this->calcularMonto()*(100 - $this->calcularDescuento())/100;
return number_format($total, 2, '.', '');
}
//Eliminar producto del carrito por su codigo
//En este caso lo que hacemos es recorrer los productos, luego preguntamos si el código de producto
//es diferente al código que estamos mandando, si es así entonces llenaremos los productos en un nuevo
//arreglo $pro2, luego de eso reemplazamos el atributo productos por el valor del arreglo $pro2.
public function eliminarProducto($codigo){
$pro2 = array();
foreach ($this->productos as $indice => $producto){
if($producto->codpro!=(int)$codigo){
$pro2[]=$producto;
}
}
$this->productos=$pro2; //Reemplaza por el valor del arreglo
}
//Actualizar cantidad ingresada.
//Este metodo lo que hace simplemente es reemplazar la cantidad del producto por uno ingresada.
public function actualizarCantidadIngresada($codigo,$cantidad){
foreach ($this->productos as $indice => $producto){
if($producto->codpro==(int)$codigo){
$producto->cantidad =$cantidad; //Reemplaza la cantidad existente en el producto
}
}
}
}
?>
4.Pasamos a crear la clase: ProductoDAO.class.php
<?php
//Incluimos las 2 clases necesarias para realizar la consulta. a la BD.
require_once ('Producto.class.php');
require_once ('Conexion.class.php');
class ProductoDAO{
public $conexion; //Variable que contendra el resultado de la conexion
public function __construct() {
$this->conexion = new Conexion(); //Instanciamos el metodo Conexion de la clase Conexion.class.php
}
//Recupero en un array todos los productos en forma de objetos de la base de datos
public function obtenerProductos(){
$productos = array();
$result = $this->conexion->ejecutar("select codpro, nompro, prepro from producto");
while($array = mysql_fetch_array($result)){
//Creo una instanacia de producto y lo almanceo en el array
$productos[] = new Producto($array['codpro'],$array['nompro'],$array['prepro']);
}
return $productos;
}
//Recupero un producto de foma de objeto de la base de datos indicandole su código
public function obtenerProducto($codigo){
$producto = null;
$sql = "select codpro, nompro, prepro from producto where codpro=". mysql_escape_string($codigo);
$result = $this->conexion->ejecutar($sql);;
if($array = mysql_fetch_array($result)){
//Creo una sola instancia que será devuelta..
$producto = new Producto($array['codpro'],$array['nompro'],$array['prepro']);
}
return $producto;
}
//Funcion para guardar una Factura y su Detalle, recibirá como parámetros.
//$productos - que contndra todos los productos agregados al carrito
//$mon - El monto total de todo los productos
//$des - El descuento total de todos los productos
//$tot - El total de todo los productos
function guardarFactura($productos,$mon,$des,$tot){
//Autocommit = 0
mysql_query("SET AUTOCOMMIT=0;"); //Para InnoDB, sirve para mantener la transaccion abierta
//Inicio de transacción
mysql_query("BEGIN;");
//Operaciones en la Factura
//Para este usaremos el codigo de 1 cliente
$sql = "insert into factura (codcli,facfec,facmon,facdes,factot) ";
$sql .= "values (1, now(),$mon,$des,$tot)";
$rs =$this->conexion->ejecutar($sql);
if(!$rs){
echo "Error en la Transacción: ".mysql_error();
mysql_query("ROLLBACK;"); //Terminar la transaccion si hay error
exit();
}
//Recuperamos el ID generado en el insert de la tabla "factura"
$facnum = mysql_insert_id();
//Recorremos e insertamos todos los productos a la tabla facdeta, todos con el mismo Id.
foreach($productos as $producto){
$sql1 = "INSERT INTO facdeta(codpro,facnum,cantidad,precio,total)";
$sql1 .= "values ($producto->codpro,$facnum, $producto->cantidad,$producto->prepro,{$producto->precioTotal()})";
$rs = $this->conexion->ejecutar($sql1);
if(!$rs){
echo "Error en la Transacción: ".mysql_error();
mysql_query("ROLLBACK;"); //Terminar la transaccion si hay error
exit();
}
}
if ($rs) {
mysql_query("COMMIT"); //Terminar la transaccion
}
return $facnum; //Retornamos el id
}
}
?>
5. Por último tenemos en index. Acá se hará todas las transacciones..
<?php
//Incluimos los 2 archivos para realizar toda la transacción
require_once ('Carrito.class.php');
require_once ('ProductoDAO.class.php');
session_start(); //Inicamos todas las sesiones
//Creamos al objeto carrito vacio con un identificador de sesion
$carrito = new Carrito(session_id());
//Recupero el objeto carrito de la sesion en caso exista
if(isset($_SESSION['carrito'])) $carrito = $_SESSION['carrito'];
//Si el usuario realizo una acción
if(isset ($_GET['action'])){
//Si el cliente ha seleccionado un producto
switch ($_GET['action']){
case 'agregar':
//Recupero el producto de codigo indicado en la base de datos
$productoDAO = new ProductoDAO();
$producto = $productoDAO->obtenerProducto((int)$_GET['idProducto']);
//Agrego al carrito de compras el producto recuperado de la base de datos
$carrito->agregarProducto($producto);
break;
case 'vacear':
//Reemplazo el atributo carrito de la sesion con un objeto carrito sin productos
$carrito = new Carrito(session_id());
break;
case 'eliminar':
//Llamo al metodo eliminarProducto retorno todos los productos menos el del código incicado
$carrito->eliminarProducto((int)$_GET['idProducto']);
break;
case 'actualizar':
//Atrapamos el nombre y valor de todos los textbox...
//Luego vemos si tanto el codigo y la cantidad son mayores que 0.
//Y actualizamos la cantidad 1 a 1 de cada producto
foreach($_GET as $codigo => $cantidad){
if((int)$codigo > 0 && (int)$cantidad > 0){
//Actualizamos la cantidad para un mismo producto
$carrito->actualizarCantidadIngresada($codigo, $cantidad);
}
}
break;
case 'guardar':
$productoDAO = new ProductoDAO();
$facnum = $productoDAO->guardarFactura($carrito->productos,$carrito->calcularMonto(),$carrito->calcularDescuento(),$carrito->calcularPrecioTotal());
break;
}
//Guardo nuevamente el carrito de la session
$_SESSION['carrito'] = $carrito;
header('Location: index.php'); //Regresamos ala pagina Inicial
exit(); //Paramos el script
}
?>
<html>
<head>
<style>
.link_button{
background-color:#444444;
color:#FFFFFF;
font-family:Arial, Helvetica, sans-serif;
font-size:12px;
font-weight:bold;
border: 1px solid #7F7F7F;
padding: 2px 3px 2px 3px;
cursor:pointer;
}
.productos_listado{
table-layout:fixed;
width:650px;
border: 1px solid #D3D4DF;
font-family:Arial, Helvetica, sans-serif;
font-size:12px;
}
.productos_listado caption{
background-color: #333333;
font-family:Arial, Helvetica, sans-serif;
font-size:14px;
font-weight:bold;
color:#FFFFFF;
padding:8px 0px 8px 0px;
}
.productos_listado th{
background-color: #D3D4DF;
color:#333333;
}
.productos_listado td{
height:24px;
}
.productos_listado td.td_linea{
height: 2px;
background-color: #333333;
padding: 2px 0px 4px 3px;
}
</style>
</head>
<body topmargin="0" leftmargin="0">
<div align="center" class="content">
<form action="index.php" method="get">
<table border="0" class="productos_listado">
<caption>Listado de Productos</caption>
<tr>
<th width="70px">Código</th>
<th>Detalle</th>
<th width="80px">Precio</th>
<th width="50px">Add</th>
</tr>
<?php
//Recuperando datos de los productos
$productoDAO = new ProductoDAO;
$productos = $productoDAO->obtenerProductos();
//Listamos todos los productos
foreach ($productos as $producto){
?>
<tr>
<td align="center"><b><?php echo $producto->codpro ;?></b></td>
<td><?php echo $producto->nompro ;?></td>
<td align="center">S/.<?php echo $producto->prepro ;?></td>
<td align="center">
<a href="javascript:void(0);"
onclick="window.location='index.php?action=agregar&idProducto=<?php echo $producto->codpro ;?>';">
<img src="img/shopcart.png" alt="Agregar" border="0" title="Agregar"/>
</a>
</td>
</tr>
<?php
}
?>
</table>
<br />
<hr>
<?php
$total = 0;
//Si existe al menos un producto se generará todo lo demas.
if(count($carrito->productos)>0){
?>
<table border="0" class="productos_listado">
<caption>Carrito de compras</caption>
<tr>
<th width="40"> </th>
<th width="60">Cant.</th>
<th width="70">Código</th>
<th>Nombre</th>
<th width="90">Precio unit.</th>
<th width="90">Precio total</th>
</tr>
<?php
//Listamos los productos insertados al carrito
foreach($carrito->productos as $producto){
?>
<tr>
<td align="center">
<a href="javascript:void(0);"
onClick="window.location='index.php?action=eliminar&idProducto=<?php echo $producto->codpro ;?>';">
<img src="img/bin_closed.png" alt="Eliminar" border="0" title="Eliminar"/>
</a>
</td>
<td align="center">
<input type="text" name="<?php echo $producto->codpro ;?>"
value="<?php echo $producto->cantidad ;?>" maxlength="3" size="4" style="text-align: center" />
</td>
<td align="center"><?php echo $producto->codpro ;?></td>
<td align="center"><?php echo $producto->nompro ;?></td>
<td align="center">S/.<?php echo $producto->prepro ;?></td>
<td align="center">S/.<?php echo $producto->precioTotal() ;?></td>
</tr>
<?php
}
?>
<tr>
<td class="td_linea" colspan="6"></td>
</tr>
<tr>
<td colspan="5" align="left">
<b>Monto:</b>
</td>
<td align="center">S/.<?php echo $carrito->calcularMonto(); ?></td>
</tr>
<tr>
<td colspan="5" align="left">
<b>Cantidad:</b>
</td>
<td align="center"><?php echo $carrito->calcularCantidad(); ?></td>
</tr>
<tr>
<td colspan="5" align="left">
<b>Descuento:</b>
</td>
<td align="center">%<?php echo $carrito->calcularDescuento() ; ?></td>
</tr>
<tr>
<td colspan="5" align="left">
<b>Total:</b>
</td>
<td align="center">S/.<?php echo $carrito->calcularPrecioTotal() ; ?></td>
</tr>
</table>
<input type="button" value="Vacear Cesta" class="link_button" style="width:130px;"
onClick="parent:location='index.php?action=vacear'"/>
<input type="hidden" name="action" value="actualizar" style="width:130px;"/>
<input type="submit" value="Actualizar" class="link_button" style="width:130px;"/>
<!--<input type="submit" value="Guardar" name="guardar" class="link_button" style="width:130px;"/>-->
<input type="button" value="Grabar" class="link_button" style="width: 130px"
onclick="parent:location='index.php?action=guardar';">
<?php
//var_dump($carrito);
?>
<?php
}else
echo 'No tiene ningun producto'; //Si no hay producto en el carrito se muestra un mensaje
?>
</form>
</div>
</body>
</html>
---------------------------------------------------------------------------------------------------
Bueno esto es todo, como dije antes espero que les sirva para poder realizar trabajos más complejos en adelante usando la POO y la base de datos MYSQL.
Aca la descarga del archivo... (' ' ,)
Descargar
Saludos, Muchas gracias por compartir tu conocimiento. ojala y sigas a delante con tu blog
ResponderEliminarexcelente aporte muchas gracias los estoy revisando y modificando para un trabajo que necesito. Saludos
ResponderEliminarMuchas gracias, estaba perdido y ahora ya se como gracias de nuevo
ResponderEliminaramigo disculpa sabes como puedo agregar productos?
Eliminarerror en la linea 24 ayuda porfavor
ResponderEliminarmuy bueno, muchas gracias
ResponderEliminarLa tienda va genial, un 10; llevaba tiempo buscandolo porque no hay quien entienda a algunos profesores. No buscarás trabajo?
ResponderEliminarGracias!