Umas das dúvidas recorrente que recebo sobre a minha vídeoaula de carrinho de compras, é relacionado em adicionar opções aos produtos. Exemplo, vender camisas, e a pessoa ter a opção das cores.
Na vídeoaula ensino adicionar os produtos numa session, onde é atribuído um array, sendo o ID a chave desse array, e o valor será a quantidade. Dessa maneira você consegue recuperar o valor do produto do banco.
Mas como adicionar opções de cores na session, sendo que adicionamos apenas o ID do produto e quantidade? Primeiro coisa que pensamos é estendê-lo em vez de apenas atribuir a quantidade, atribuir um array, tendo assim os valores de quantidade e cor:
$_SESSION['carrinho'][ID] = array('qtd' => 1, 'cor_id' => 5);Conseguimos adicionar o ID da cor no carrinho, mas tem um problema. Se a pessoa quiser o mesmo produto, com cores diferentes? Como o ID do produto é o que definir no array os valores diferentes, se atribuiu outra cor com o mesmo produto, ele vai sobrescrever. Então precisamos ter um identificador único, onde vamos dizer qual o produto e cor. Podendo ter um produto com várias cores. E que tal utilizamos essas duas informações como índice desse array?
$_SESSION['carrinho'][ID:COR_ID] = 1;Pronto, resolvemos o nosso problema, separamos com o valor por dois pontos ( : ), sendo o primeiro o ID e o segundo a ID da cor do produto. Então vamos exemplificar melhor isso. Criaremos uma classe chamado Carrinho.php, e que terá todos o processo relacionado ao carrinho de compras. O código está comentado, para facilitar a compreensão :
Carrinho.php
<?php /** * * Implementa o carrinho de compras * @author David CHC * */ final class Carrinho{ /** * * Método construtor * Caso não existe a $_SESSION['carrinho'], * ele criar atribuindo um array vazio * */ public function __construct(){ if(!isset($_SESSION['carrinho'])){ $_SESSION['carrinho'] = array(); } } /** * * Adiciona um produto ao carrinho * * Veja que criar uma chave, tendo a composição de 2 items: * o ID do produto e o ID da cor do produto * Essa maneira não irá sobreescrever quando quiser * vários produtos com cores diferentes. * * Um detalhe, se não tiver cor, ele atribui o valor zero, * facilitando na hora de verificar se tem cor ou não * * @param integer $id é código do produto adicionado * @param integer $qtd é quantidade * @param integer $cor_id é a cor do produto * */ public function adicionar($id, $qtd = 1, $cor_id=null){ //verificar se o valor é nulo if(is_null($cor_id)){ //Se for, monta o indice, sendo o valor para cor como 0 $indice = sprintf('%s:%s', (int)$id, 0); }else{ //Se existe um valor, atribui ao indice $indice = sprintf('%s:%s', (int)$id, (int)$cor_id); } /** * Se não existir esse indice no carrinho * Atribui ao carrinho com a quantidade */ if(!isset($_SESSION['carrinho'][$indice])){ $_SESSION['carrinho'][$indice] = (int)$qtd; } } /** * * Altera a quantidade do carrinho * O indice do array é a junção do ID do produto com o ID da cor * * @param string $indice é a chave do array * @param integer $qtd é quantidade para alterar */ public function alterar($indice, $qtd){ //verifica se existe esse indice if(isset($_SESSION['carrinho'][$indice])){ //se o quantidade for maior que zero if($qtd > 0){ //realiza a alteração $_SESSION['carrinho'][$indice] = (int)$qtd; } } } /** * * Excluir o produto do carrinho * @param string $indice */ public function excluir($indice){ //excluir o produto do carrinho unset($_SESSION['carrinho'][$indice]); } /** * * Retorna um array com os dados dos produtos no carrinho * @return array $result */ public function listarProdutos(){ //inicia a variável com array $result = array(); foreach($_SESSION['carrinho'] as $indice => $qtd){ //Separa o ID do produto do ID da cor list($id, $cor_id) = explode(':', $indice); //Realizar a busca pelo produto, selecionado apenas o nome do produto e preço $query_product = mysql_query("SELECT produto, preco FROM produtos WHERE id = '$id'"); //retorna os itens do tabela produtos $row_product = mysql_fetch_assoc($query_product); /** * Adicionar ao array o nome do produto, preço , quantidade, subtotal e a cor * È importante reparar que indice desse array será o mesmo * do carrinho. */ $result[$indice]['produto'] = $row['produto']; $result[$indice]['preco'] = $row['preco']; $result[$indice]['qtd'] = $row['qtd']; $result[$indice]['subtotal']= $row['preco'] * $row['qtd']; $result[$indice]['cor'] = ''; //Verifica se existe cor para o produto if($cor_id > 0) { //Faz a busca pela cor , seleciona apenas o nome da cor $query_cor = mysql_query("SELECT cor FROM cores WHERE id = '$cor_id'"); //retorna os itens do tabela cores $row_cor = mysql_fetch_assoc($query_cor); //Adiciona o nome da cor $result[$indice]['cor'] = $row_cor['cor']; } } return $result; } /** * * Retorna o valor total do carrinho * Aqui apenas listaremos o produtos * somaremos o subtotal, que é * o preço vezes a quantidade * Isso já foi calculado no método listarProdutos */ public function valorTotal(){ //listar todos os produtos $produtos = $this->listarProdutos(); //inicia a variável $total = 0; //listar os produtos, para resgatar o subtotal foreach($produtos as $indice => $row){ //realiza a soma $total += $row['subtotal']; } return $total; } } ?>Veremos como seria utilizado essa classe, lembrando que não irei mostrar todo os processos desse carrinho do compras, porque tem uma videoaula que explica o mesmo procedimento, estou apenas mostrando como usar a classe. Antes os valores eram enviado por GET , mesmo na hora da alteração, agora será enviado por POST. Vamos ao código :
carrinho.php
<?php //Inicia a Session session_start(); //inclui a conexão require('config/conexao.php'); //Include a classe Carrinho.php require('classes/Carrinho.php'); //Instancia o Carrinho $cart = new Carrinho(); //Verifica se irá adicionar produto ao carrinho if(isset($_POST['acao']) && $_POST['acao'] == 'add'){ /** * * Resgata o ID do produto * Resgata o ID da cor * Resgata a Quantidade * */ $id = $_POST['id']; $cor_id = (isset($_POST['cor_id'])) ?$_POST['cor_id'] : null; $qtd = $_POST['qtd']; //Adicionar o produto no carrinho $cart->adicionar($id, $qtd, $cor_id); } //Verifica se vai alterar o produto if(isset($_POST['acao']) && $_POST['acao'] == 'alterar'){ //Percorre o array da quantidade para resgatar // o indice e valor da quantidade foreach($_POST['qtd'] as $indice => $valor){ $cart->alterar($indice, $valor); } } //Verifica para excluir o produto if(isset($_GET['apagar'])){ $cart->excluir($_GET['apagar']); } //retorna todos produtos do carrinho $produtos = $cart->listarProdutos(); //retorna valor do total do carrinho $total = $cart->valorTotal();Agora vamos a parte de mostrar os produtos no carrinho, será continuação do arquivo carrinho.php, estou colocando separado para ficar mais fácil de visualizar:
<table> <thead> <tr> <th>Produto</th> <th>Quantidade</th> <th>Preço</th> <th>SubTotal</th> <th>Excluir</th> </tr> </thead> <form action="" method="post"> <tfoot> <tr> <td colspan="5"> <input type="submit" value="Alterar o Carrinho" /> <input type="hidden" name="acao" value="alterar" /> </td> </tr> </tfoot> <tbody> <?php foreach($produtos as $indice => $valor) :?> <tr> <td><?php echo $row['produto']. ' - '.$row['cor']?></td> <td><input type="text" name="qtd[<?php echo $indice?>]" value="<?php echo $valor['qtd']?>" /></td> <td>R$ <?php echo number_format($valor['preco'], 2, ',', '.')?></td> <td>R$ <?php echo number_format($valor['subtotal'], 2, ',', '.')?></td> <td><a href="carrinho.php?apagar=<?php echo $indice?>">Excluir</a></td> </tr> <?php endforeach;?> </tbody> </form> </table>Repare que o principio é o mesmo que foi utilizado na videoaula, apenas adicionamos mais uma informação. Caso você tenha muitas opções ao pedido, você pode realizar o mesmo procedimento, mas em vez de você colocar id da cor, você iria utilizar o array com todas as opções, utilizando o serialize no array, e Codifica dados (criptografar) com base64_encode , podendo reverter:
<?php $options = array('cor_id' => 1, 'tamanho_id' => 5); $id = 1; $indice = $id.':'.base64_encode(serialize($options)); ?>Depois para usar os itens é só reverter:
<?php list($id, $options) = explode(':', $indice); $items = unserialize(base64_decode($options)); ?>A partir dai você consegue com facilitada atribuir opções a seus produtos utilizando a session. Espero ter ajudado, e até a próxima