Objota O mundo orientado a objetos

Carrinho de compras orientado a objetos

Posted on setembro 1, 2010

Carrinho de compras, por vezes temos curiosidade de saber qual é a melhor forma de implementar um. De fato não existe "melhor forma" existe a forma que funciona para a sua necessidade. Então vamos lá.

O objetivo deste artigo é mostrar como implementar um carrinho de compras utilizando sessão.

Para iniciar uma sessão e registrar variáveis nela é preciso iniciá-la com session_start(). Você pode ver nos seus cookies que vai aparecer um PHPSESSID que só permanecerá em seu computador durante a sua navegação no site. E bom, de fato isso é só pra te identificar.

Coloque esse session_start() no seu config.php

Quando jogamos variáveis ou objetos dentro de uma variavel de sessão o php gera um cookie no servidor, um arquivo de texto. Por isso não precisamos ficar com tanto medo de "sobrecarregar" a memória, pois isso fica no disco rígido e não na memória do servidor.

E qual é a grande vantagem de utilizar sessão, é que ela pode ser recuperada enquanto o usuário estiver navegando em seu site. Em qualquer lugar do seu site é possível criar uma veriavel na sessão e recuperá-la quando necessário.

Como seria isso?? Simples, você tem três paginas:

>index.php
>catalogo.php
>formulario.php

Vamos supor que o usuário navega pela index.php (session_start() já foi acionado lá no config), ele já tem uma PHPSESSID. Agora ele vai para o "catalogo.php" e escolhe alguns produtos. Ou seja, ele joga no carrinho (na sessão). A partir de agora é possível recuperar esse conteúdo em qualquer página fazendo a seguinte verificação:

	if(isset($_SESSION["nomeDaMinhaVariavel"])){
	//Entrou aqui, quer dizer que o valor existe.
	// e que você pode recuperá-la
	}

Bom, vamos então a nossa implementação, vamos criar um objeto Carrinho. E o objetivo deste carrinho é armazenar produtos. Vamos considerar os seguintes atributos para produto: id , nome, descricao.

id para podermos referenciar o produto escolhido, o nome do produto e uma breve descrição. Pois quando o usuário clicar em visualizar carrinho ele terá estas informações mais básicas para ver.

Vejamos a classe Carrinho, coloque ela no arquivo Carrinho.class.php para usar __autoload(), do último artigo!

Produto.class.php

<?php
class Produto{
	private $id;
	private $nome;
	private $descricao;
	private $quantidade;
	public function Produto($id, $nome, $descricao, $quantidade=1){
		$this->id = $id;
		$this->nome = $nome;
		$this->descricao = $descricao;
		$this->quantidade = $quantidade;
	}
	public function getQuantidade() {
		return $this->quantidade;
	}
	public function setQuantidade($quantidade) {
		$this->quantidade = $quantidade;
	}
	public function getId() {
		return $this->id;
	}
	public function getNome() {
		return $this->nome;
	}
	public function getDescricao() {
		return $this->descricao;
	}
	public function setId($id) {
		$this->id = $id;
	}
	public function setNome($nome) {
		$this->nome = $nome;
	}
	public function setDescricao($descricao) {
		$this->descricao = $descricao;
	}
}
?>

Carrinho.class.php

<?php
class Carrinho{
	private $produto;
	public function Carrinho(){}
        //Adiciona um produto
	public function addProduto(Produto $m){
		$this->produto[] = $m;
	}
        // Recupera um produto pelo id
	public function getProduto(int $idProduto){
		foreach($this->produto as $pro){
			if($pro->getId() == $idProduto){
				return $pro;
			}
		}
	}
        // Remove um produto pelo id
	public function removeProduto(int $idProduto){
		for($i=0;$i < count($this->produto);$i++){
			if($this->produto[$i]->getId() == $idProduto){
				unset($this->produto[$i]);
			}
		}
	}
        // lista todos os produtos
	public function listar(){
		foreach($this->produto as $pro){
			echo "<b>Código:</b> {$pro->getId()}<br/>
				  <b>Nome:</b> {$pro->getNome()}<br/>
				  <b>Descrição:</b> {$pro->getDescricao()}<br/>
				  --------------------<br/>";
		}
	}
}
?>

Depois de já criadas as entidades, vamos ao config, e depois as paginas que irão criar e recuperar o carrinho da sessão.

Config.php

Onde vamos configurar o __autoload()

<php
function __autoload($nomeClasse){
	//Verifica se existe a classe no diretório classes
	if(file_exists("classes/".$nomeClasse.".class.php")){
		//Se existe carrega
		include_once("classes/".$nomeClasse.".class.php");
	}
}
session_start();
?>

index.php

Onde vamos carregar o nosso produto

<php
include_once("config.php");

//Inicio o carrinho
$Carrinho = new Carrinho();

//Joga na sessão
$_SESSION["carrinho"] = $Carrinho;

//inicio dois produtos
$produto1 = new Produto(23,"Chave de Fenda","Chave de fenda blindada, com ponta em diamante");
$produto2 = new Produto(354,"Batedeira","Batedeira Braslenp, com três velocidades");

//Adiciona produto 1
$_SESSION["carrinho"]->addProduto($produto1);

//Adiciona produto 2
$_SESSION["carrinho"]->addProduto($produto2);

//Link para a página carrinho.php
echo "<a href=\"carrinho.php\">Meu carrinho</a>";
?>

Carrinho.php

Onde iremos recuperar o nosso produto da sessão

<?php
include_once("config.php");
//Recupera objetos da sessão
?>

<h2>Produtos no meu carrinho:</h2><br/>
<?php
if(isset($_SESSION["carrinho"])){
	$_SESSION["carrinho"]->listar();
}
else{
	echo "Não existem produtos no seu carrinho";
}
?>

Agora é só testar. utilize a estrutura de diretórios sugerida, ou uma de sua preferência.

Estrutura:
>index.php
>config.php
>carrinho.php
>classes>Carrinho.class.php
>classes>Produto.class.php

É isso meus caros, dúvidas e sugestões! postem aí. E até a próxima!

Posted by Rodrigo Ireno

Comentários (19) Trackbacks (0)
  1. Ótimo post
    a parte do
    Coloque esse session_start() no seu config.php
    é a pagina config.php?

    []’s

    • Isso mesmo, é pq geralmente se inclui o arquivo config.php em quase todos os arquivos do site.

      Isso possibilita que a sessão persista por todo o site.

      [ a sessão persiste em todas as páginas que possuirem session_start() ]

  2. ola rodrigo, como seria para deletar o item?

    • Você poderia usar a funcão removeProduto() implementada aí em cima. As vezes pode acontecer de o objeto ficar grande de mais. Então é preciso serializá-lo antes de guardar em session.

      A serialização transforma o objeto em um formato de string padrão para transportá-lo.

      para guardar serialize(); e para pegar de volta unserialize()

      vlw

  3. Muito bom seu post, continue assim criando excelentes postagens.

  4. Olá, estou começando a aprender orientação a objetos em php..
    Gostaria de utilizar a function listar() e junto a lista que exibe, um botao para remover oproduto..
    Como posso utilizar isto? Dentro da própria função listar? Ou existe algum outro método?
    Obrigado.

    • Faça as coisas separadamente, neste caso o ideal é ter uma função remover(), algo como
      remover([id=int])

      remove o produto com um determinado ID, um numero que o identifica na lista..

  5. Rodrigo, estou tentando remover itens, utilizando a sua função, mas não estou conseguindo..

    Segue a parte:

    ‘$_SESSION[“carrinho”]->removeProduto($_GET[“id”]);’

    estou utilizando uma variavel pela url, por isso o ‘$_GET[‘id’]’.

    o engraçado que se eu adiciono 1 item e deleto, funciona, mas quando eu adiciono mais de 1 item, da problema e não deleta.

    • coloque um echo abaixo de unset($this->produto[$i]);
      pra verificar se o objeto está mesmo sendo removido do array.

      • é, realmente o item não esta sendo removido do array, segue erro: ‘Fatal error: Call to a member function getId() on a non-object in’

        • Bom isso mostra que a função getId() está sendo chamado em alguém que não é objeto.

          • public function removeProduto($idProduto){
            for($i=0;$i produto);$i++){
            if($this->produto[$i]->getId() == $idProduto){
            unset($this->produto[$i]);
            }
            }
            }

          • Não sei se mencionei isso, mas enfim. Objeto que estão na sessão tem um limite de tamanho. Se você possui um número muito grande de objetos em uma lista como essa, talvez seja preciso serializar o objeto antes de colocar na sessão e, ao recuperar o objeto da sessão, deserializar para poder utilizá-lo. Se ainda não está fazendo isso comece a pensar em fazer.

            para ver se as coisas estão dando certo comente o if e use o seguinte trecho:

            var_dump( $this->produto[$i] ) // ou var_export();

            e veja qual o tipo de objeto que está vindo, e se realmente é um objeto.
            vlw

  6. E como faço para somar todos os produtos? exemplo

    produto 1 = 10,00 reais ( unidade ) quantidade = 1 ( valor 10 )
    produto 2 = 50,00 reais ( unidade ) quantidade = 2 ( valor 100,00)

    Valor total = 110,00 ( como faço para pegar o valor total?

  7. Consegui resolver 🙂

    public function Total(){
    $this->carrinho = $_SESSION[“carrinho”];
    $total = 0;

    foreach($this->produto as $produto) {
    $total += $produto->getValor() * $produto->getQuantidade();
    }
    return $total;

    }

  8. Rafael, Estou tentando fazer 2 coisas e não estou conseguindo, poderia me ajudar porfavor ?

    1 – tentando excluir algum item do carrinho pelo id codigo

    public function removeProduto(int $idProduto){
    for($i=0;$i produto);$i++){
    if($this->produto[$i]->getId() == $idProduto){
    unset($this->produto[$i]);
    }
    }
    }

    Fazendo assim para remover $_SESSION[“carrinho”]->removeProduto(‘22714159’); não remove o produto.

    coloquei na função para extrair os resultados do session assim para saber o que está pegando :

    var_dump($_SESSION[“carrinho”]);

    ele traz o seguinte resultado .

    object(Carrinho)#1 (1) { [“produto”]=> array(1) { [0]=> object(Produto)#2 (4) { [“id”]=> string(8) “22714159” [“nome”]=> string(10) “Dedicado 2” [“valor”]=> string(6) “600.00” [“quantidade”]=> int(1) } } }

    como resolver isso para excluir esse item pelo id ?

    2 – Como posso colocar para vereficar se existe no session, um produto para vereficar se ja existe algum item, para caso o item existe no carrinho não adicionar ele novamente e sim icrementar + 1 quantidade?

    3 – Como atualizar pelo id aumentar 1 quantia ?

  9. Não exclui o produto, estou fazendo da seguinte forma meu codigo

    URL para excluir : http://localhost/teste.php?action=excluir

    Teria que excluir o produto 1 e não exclui

    addProduto($produto1);

    //Adiciona produto 2
    $_SESSION[“carrinho”]->addProduto($produto2);

    $action = $_GET[“action”];

    switch ($action) {
    case “excluir”:

    echo “deletou”;
    $_SESSION[“carrinho”]->removeProduto(22714159);
    break;

    }

    ?>

  10. Não exclui o produto, estou fazendo da seguinte forma meu codigo
    URL para excluir : http://localhost/teste.php?action=excluir
    Teria que excluir o produto 1 e não exclui como resolver?

    //Inicio o carrinho
    $Carrinho = new Carrinho();

    //Joga na sessão
    $_SESSION[“carrinho”] = $Carrinho;

    //inclui o produto 1
    $produto1 = new Produto(22714159,”Dedicado 2″,600.00);

    //inclui o produto 2
    $produto2 = new Produto(123,”Dedicado 1″,200.00);

    //Adiciona produto 1
    $_SESSION[“carrinho”]->addProduto($produto1);

    //Adiciona produto 2
    $_SESSION[“carrinho”]->addProduto($produto2);

    $action = $_GET[“action”];

    switch ($action) {
    case “excluir”:

    echo “deletou”;
    $_SESSION[“carrinho”]->removeProduto(22714159);
    break;

    }

  11. como seria esse carrinho com variação de preço por produto?


Leave a comment

Sem trackbacks