Volver
Ctrl+Space
◑
Copiar
Descargar
Restaurar
Ejecutar
Ctrl+Enter
<?php // POO en PHP - Ejemplo 4: Carrito de compras // ============================================ // Sistema completo que combina clases, encapsulamiento, // composición y métodos estáticos. class Producto { private static int $contador = 0; public int $id; public function __construct( public string $nombre, public float $precio, private int $stock ) { self::$contador++; $this->id = self::$contador; } public function getStock(): int { return $this->stock; } public function disponible(): bool { return $this->stock > 0; } public function reservar(int $cantidad): bool { if ($cantidad > $this->stock) return false; $this->stock -= $cantidad; return true; } public function devolver(int $cantidad): void { $this->stock += $cantidad; } public static function totalCreados(): int { return self::$contador; } } class ItemCarrito { public function __construct( public Producto $producto, public int $cantidad ) {} public function subtotal(): float { return round($this->producto->precio * $this->cantidad, 2); } } class Carrito { private array $items = []; private string $titular; private static int $totalPedidos = 0; public function __construct(string $titular) { $this->titular = $titular; } public function agregar(Producto $producto, int $cantidad = 1): bool { if ($cantidad <= 0) { echo " ✗ Cantidad inválida.\n"; return false; } if (!$producto->reservar($cantidad)) { echo " ✗ Stock insuficiente para \"" . $producto->nombre . "\" (stock: " . $producto->getStock() . ").\n"; return false; } // Si ya está en el carrito, sumamos foreach ($this->items as $item) { if ($item->producto->id === $producto->id) { $item->cantidad += $cantidad; echo " ✓ \"" . $producto->nombre . "\" actualizado a " . $item->cantidad . " unidades.\n"; return true; } } $this->items[] = new ItemCarrito($producto, $cantidad); echo " ✓ \"" . $producto->nombre . "\" x" . $cantidad . " agregado.\n"; return true; } public function quitar(Producto $producto): bool { foreach ($this->items as $i => $item) { if ($item->producto->id === $producto->id) { $producto->devolver($item->cantidad); array_splice($this->items, $i, 1); echo " ✓ \"" . $producto->nombre . "\" quitado del carrito.\n"; return true; } } echo " ✗ \"" . $producto->nombre . "\" no estaba en el carrito.\n"; return false; } public function total(): float { $total = 0; foreach ($this->items as $item) { $total += $item->subtotal(); } return round($total, 2); } public function totalConDescuento(float $pct): float { return round($this->total() * (1 - $pct / 100), 2); } public function estaVacio(): bool { return empty($this->items); } public function confirmarPedido(): void { if ($this->estaVacio()) { echo " ✗ El carrito está vacío.\n\n"; return; } self::$totalPedidos++; echo "\n ========================================\n"; echo " PEDIDO #" . self::$totalPedidos . " — " . $this->titular . "\n"; echo " ========================================\n"; foreach ($this->items as $item) { $linea = " " . $item->producto->nombre . " x" . $item->cantidad; $precio = " $" . $item->subtotal(); echo str_pad($linea, 36) . str_pad($precio, 10, " ", STR_PAD_LEFT) . "\n"; } echo " ----------------------------------------\n"; echo str_pad(" TOTAL", 36) . str_pad(" $" . $this->total(), 10, " ", STR_PAD_LEFT) . "\n"; echo " ========================================\n"; echo " ✓ Pedido confirmado.\n\n"; $this->items = []; } public static function totalPedidos(): int { return self::$totalPedidos; } } // ── Simulación ──────────────────────────────────────────────────────────── $laptop = new Producto("Laptop", 1200.00, 5); $mouse = new Producto("Mouse", 25.50, 20); $teclado = new Producto("Teclado", 75.00, 10); $monitor = new Producto("Monitor", 450.00, 3); $auricular = new Producto("Auricular", 60.00, 0); // sin stock echo "=== Catálogo ===\n"; foreach ([$laptop, $mouse, $teclado, $monitor, $auricular] as $p) { $estado = $p->disponible() ? "stock: " . $p->getStock() : "SIN STOCK"; echo " [" . $p->id . "] " . $p->nombre . " — $" . $p->precio . " (" . $estado . ")\n"; } echo "Productos creados: " . Producto::totalCreados() . "\n"; echo "\n=== Carrito de Ana ===\n"; $carritoAna = new Carrito("Ana García"); $carritoAna->agregar($laptop, 1); $carritoAna->agregar($mouse, 2); $carritoAna->agregar($auricular, 1); // sin stock $carritoAna->agregar($laptop, 10); // excede stock $carritoAna->agregar($mouse, 1); // ya estaba — suma echo "\n Total: $" . $carritoAna->total() . "\n"; echo " Con 10% descuento: $" . $carritoAna->totalConDescuento(10) . "\n"; $carritoAna->confirmarPedido(); echo "=== Carrito de Carlos ===\n"; $carritoCarlos = new Carrito("Carlos López"); $carritoCarlos->agregar($monitor, 2); $carritoCarlos->agregar($teclado, 1); $carritoCarlos->quitar($monitor); $carritoCarlos->agregar($mouse, 3); $carritoCarlos->confirmarPedido(); echo "Total de pedidos realizados: " . Carrito::totalPedidos() . "\n"; echo "\n=== Stock restante ===\n"; foreach ([$laptop, $mouse, $teclado, $monitor] as $p) { echo " " . $p->nombre . ": " . $p->getStock() . " unidades\n"; } ?>