Solucionado (ver solução)
Solucionado
(ver solução)
11
respostas

Dificuldade nos getters e setters

Segue o erro apresentado:

Fatal error: Uncaught Error: Call to a member function getNome() on null in C:\xampp\htdocs\loja\Projeto-de-php\loja\produto-lista.php:20 Stack trace: #0 {main} thrown in C:\xampp\htdocs\loja\Projeto-de-php\loja\produto-lista.php on line 20

Segue os códigos: adiciona-produto.php, altera-produto.php, banco-categoria.php, banco-produto.php, produto-altera-formulario.php, produto-formulario-base.php, produto-formulario.php e produto-lista.php.

adiciona-produto.php:

<?php 
require_once("cabecalho.php");
require_once("banco-produto.php");
require_once("logica-usuario.php");
require_once("class/Produto.php");
require_once("class/Categoria.php");

verificaUsuario();

$categoria = new Categoria();
$categoria->getId($_POST['categoria_id']);

$produto = new Produto();
$produto->getNome($_POST['nome']);
$produto->getPreco($_POST['preco']);
$produto->getDescricao($_POST['descricao']);

if(array_key_exists('usado', $_POST)) {
    $produto->getUsado() = "true";
} else {
    $produto->getUsado() = "false";
}

$produto->getCategoria = $categoria;

if(insereProduto($conexao, Produto $produto)) { ?>
    <p class="text-success">O produto <?= $produto->getNome() ?>, <?= $produto->getPreco() ?> foi adicionado.</p>
<?php 
} else {
    $msg = mysqli_error($conexao);
?>
    <p class="text-danger">O produto <?= $produto->getNome() ?> não foi adicionado: <?= $msg?></p>
<?php
}
?>

<?php include("rodape.php"); ?>

altera-produto.php

<?php
require_once("cabecalho.php");
require_once("banco-produto.php");
require_once("class/Produto.php");
require_once("class/Categoria.php");

$categoria = new Categoria();
$categoria->id = $_POST['categoria_id'];

$produto = new Produto();
$produto->getId($_POST['id']);
$produto->getNome($_POST['nome']);
$produto->getPreco($_POST['preco']);
$produto->getDescricao($_POST['descricao']);
$produto->getCategoria($categoria);
$produto->getCategoria()->getid($_POST["categoria_id"]);
$produto->getUsado($_POST["usado"]);

if(array_key_exists('usado', $_POST)) {
    $produto->getUsado() = "true";
} else {
    $produto->getUsado() = "false";
}



if(alteraProduto($conexao, $produto)) { ?>
    <p class="text-success">O produto <?= $produto->nome ?>, <?= $produto->preco ?> foi alterado.</p>
<?php 
} else {
    $msg = mysqli_error($conexao);
?>
    <p class="text-danger">O produto <?= $produto->nome ?> não foi alterado: <?= $msg?></p>
<?php
}
?>

<?php include("rodape.php"); ?>

banco-categoria.php

<?php
require_once("conecta.php");
require_once("class/Categoria.php");

function listaCategorias($conexao) {

    $categorias = array();
    $query = "select * from categorias";
    $resultado = mysqli_query($conexao, $query);

    while($categoria_array = mysqli_fetch_assoc($resultado)) {

        $categoria = new Categoria();
        $categoria->getId($categoria_array['id']);
        $categoria->getNome($categoria_array['nome']);

        array_push($categorias, $categoria);
    }

    return $categorias;
}
11 respostas

banco-produto.php

<?php
require_once("conecta.php");
require_once("class/Produto.php");
require_once("class/Categoria.php");

function listaProdutos($conexao) {

    $produtos = array();
    $resultado = mysqli_query($conexao, "select p.*,c.nome as categoria_nome 
        from produtos as p join categorias as c on c.id=p.categoria_id");

    while($produto_array = mysqli_fetch_assoc($resultado)) {

        $categoria = new Categoria();
        $categoria->getNome($produto_array['categoria_nome']);

        $produto = new Produto();
        $produto->getId($produto_array['id']);
        $produto->getNome($produto_array['nome']);
        $produto->getDescricao($produto_array['descricao']);
        $produto->getCategoria($categoria);
        $produto->getPreco($produto_array['preco']);
        $produto->getUsado($produto_array['usado']);

        array_push($produtos, $produto);
    }

    return $produtos;
}

function insereProduto($conexao, Produto $produto) {

    $query = "insert into produtos (nome, preco, descricao, categoria_id, usado) 
        values ('{$produto->getNome()}', {$produto->getPreco()}, '{$produto->getDescricao()}', 
            {$produto->getCategoria()->getId()}, {$produto->getUsado()})";

    return mysqli_query($conexao, $query);
}

function alteraProduto($conexao, Produto $produto) {

    $query = "update produtos set nome = '{$produto->getNome()}', 
        preco = {$produto->getPreco()}, descricao = '{$produto->getDescricao()}', 
            categoria_id= {$produto->getCategoria()->getId()}, usado = {$produto->getUsado()} 
                where id = '{$produto->getId()}'";

    return mysqli_query($conexao, $query);
}

function buscaProduto($conexao, $id) {

    $query = "select * from produtos where id = {$id}";
    $resultado = mysqli_query($conexao, $query);
    $produto_buscado = mysqli_fetch_assoc($resultado);

    $categoria = new Categoria();
    $categoria->getId($produto_buscado['categoria_id']);

    $produto = new Produto();
    $produto->getId($produto_buscado['id']);
    $produto->getNome($produto_buscado['nome']);
    $produto->getDescricao($produto_buscado['descricao']);
    $produto->getCategoria($categoria);
    $produto->getPreco($produto_buscado['preco']);
    $produto->getUsado($produto_buscado['usado']);

    return $produto;
}

function removeProduto($conexao, $id) {

    $query = "delete from produtos where id = {$id}";

    return mysqli_query($conexao, $query);
}

produto-altera-formulário.php

<?php
require_once("cabecalho.php");
require_once("banco-categoria.php");
require_once("banco-produto.php");

$id = $_GET['id'];
$produto = buscaProduto($conexao, $id);
$categorias = listaCategorias($conexao);

$selecao_usado = $produto->getUsado() ? "checked='checked'" : "";
$produto->usado = $selecao_usado;

?>

<h1>Alterando produto</h1>
<form action="altera-produto.php" method="post">
    <input type="hidden" name="id" value="<?=$produto->getId()?>">
    <table class="table">
        <?php include("produto-formulario-base.php"); ?>
        <tr>
            <td>
                <button class="btn btn-primary" type="submit">Alterar</button>
            </td>
        </tr>
    </table>
</form>

<?php include("rodape.php"); ?>

produto-formulario-base.php

<tr>
    <td>Nome</td>
    <td>
        <input class="form-control" type="text" name="nome" 
            value="<?=$produto->getNome()?>">
    </td>
</tr>
<tr>
    <td>Preço</td>
    <td>
        <input class="form-control" type="number" step="0.01" name="preco" 
            value="<?=$produto->getPreco()?>">
    </td>
</tr>
<tr>
    <td>Descrição</td>
    <td>
        <textarea class="form-control" name="descricao"><?=$produto->getDescricao()?></textarea>
    </td>
</tr>
<tr>
    <td></td>
    <td><input type="checkbox" name="usado" <?=$produto->getUsado()?> value="true"> Usado
</tr>
<tr>
    <td>Categoria</td>
    <td>
        <select name="categoria_id" class="form-control">
            <?php
            foreach($categorias as $categoria) : 
                $essaEhACategoria = $produto->getCategoria()->getId() == $categoria->getId();
                $selecao = $essaEhACategoria ? "selected='selected'" : "";
            ?>
                <option value="<?=$categoria->id?>" <?=$selecao?>>
                    <?=$categoria->getNome()?>
                </option>
            <?php 
            endforeach
            ?>
        </select>
    </td>
</tr>

produto-formulario.php

<?php
require_once("cabecalho.php");
require_once("banco-categoria.php");
require_once("logica-usuario.php");
require_once("class/Produto.php");
require_once("class/Categoria.php");

verificaUsuario();

$categoria = new Categoria();
$categoria->setId(1);

$produto = new Produto();
$produto->getCategoria($categoria);

$categorias = listaCategorias($conexao);

?>    

<h1>Formulário de produto</h1>
<form action="adiciona-produto.php" method="post">
    <table class="table">

        <?php include("produto-formulario-base.php"); ?>

        <tr>
            <td>
                <button class="btn btn-primary" type="submit">Cadastrar</button>
            </td>
        </tr>
    </table>
</form>

<?php include("rodape.php"); ?>

produto-lista.php

<?php
require_once("cabecalho.php");
require_once("banco-produto.php");
require_once("logica-usuario.php");

verificaUsuario();
?>


<table class="table table-striped table-bordered">
    <?php
    $produtos = listaProdutos($conexao);
    foreach($produtos as $produto) :
    ?>
        <tr>
            <td><?= $produto->getNome() ?></td>
            <td><?= $produto->getPreco(); ?></td>
            <td><?= $produto->precoComDesconto(); ?></td>
            <td><?= substr($produto->getDescricao(), 0, 40); ?></td>
            <td><?= $produto->getCategoria()->getNome(); ?></td>

            <td>
                <a class="btn btn-primary" 
                    href="produto-altera-formulario.php?id=<?=$produto->getId()?>">
                    alterar
                </a>
            </td>
            <td>
                <form action="remove-produto.php" method="post">
                    <input type="hidden" name="id" value="<?=$produto->getId()?>">
                    <button class="btn btn-danger">remover</button>
                </form>
            </td>
        </tr>
    <?php
    endforeach
    ?>    
</table>

<?php include("rodape.php"); ?>

Ao tentar realizar a inserção de um novo produto, não é possível cadastrar uma categoria porque não me mostra a opção para selecionar.

Oi Hugo, pelo mensagem de erro, acontece quando você lista os produtos, não é isso? Cola o Produto.php aqui pra gente ver?

Produto.php

<?php

class Produto {

    private $id;
    private $nome;
    private $preco;
    private $descricao;
    private $categoria;
    private $usado;

    public function getId()
    {
        return $this->$id;
    }
    public function setId($id)
    {
        return $this->$id = $id;
    }



    public function getNome()
    {
        return $this->$nome;
    }

    public function setNome($nome)
    {
        return $this->$id = $id;
    }



    public function getPreco()
    {
        return $this->$preco;
    }
    public function setPreco($preco)
    {
        return $this->$preco = $preco;
    }


    public function getDescricao()
    {
        return $this->$descricao;
    }
    public function setDescricao($descricao)
    {
        return $this->$descricao = $descricao;
    }


    public function getCategoria()
    {
        return $this->$categoria;
    }
    public function setCategoria($categoria)
    {
        return $this->$categoria = $categoria;
    }


    public function getUsado()
    {
        return $this->$usado;
    }
    public function setUsado($usado)
    {
        return $this->$usado = $usado;
    }

    public function precoComDesconto($valor = 0.6){
        if ($valor >= 0 && $valor <= 0.5) {
            return $this->preco - ($this->preco * $valor);
        }else{
            $texto = "Desconto inválido";
            ?>
            <p class="alert-danger form-control"><?=$texto?></p>
    <?php  
        }

    }


}

?>

Fala Hugo, tudo certo?! :D

Vamos lá cara, pelo que eu entendi logo de cara ao olhar seu código foi que você está dando GET em objetos logo acima instanciados e eles vem "vazios" para que você possa SETAR valores neles e manipula-los como quiser.

Como no Exemplo abaixo. (Você "gettando" ao invés de setar os valores.)

$categoria = new Categoria();
$categoria->getId($_POST['categoria_id']);

$produto = new Produto();
$produto->getNome($_POST['nome']);
$produto->getPreco($_POST['preco']);
$produto->getDescricao($_POST['descricao']);

Recebendo os valores e setando no objeto previamente instanciado.

$categoria = new Categoria();
$categoria->setId($_POST['categoria_id']);

$produto = new Produto();
$produto->setNome($_POST['nome']);
$produto->setPreco($_POST['preco']);
$produto->setDescricao($_POST['descricao']);

Como você estava fazendo, ele pegava todos os valores dos atributos do objeto que você acabou de instanciar (NULL) e persistia no banco. Sendo assim, quando você realizava a consulta para ter o retorno dos valores, os mesmos retornavam como foram persistidos (NULOS), consistindo no erro. :)

Boa Gabriel, me parece ser esse mesmo o problema. Hugo, dá uma olhada, corrige e se tudo tiver certinho, marca a resposta do Gabriel como solução, tá bem?

Olá, entendi o que estava fazendo de errado, creio que fiz as alterações certas, publiquei os códigos no git - > https://github.com/HugoNCastro/Projeto-de-php/tree/master/loja

Após fazer as alterações conforme a explicação do Gabriel, vi que no produto-formulario.php eu não consigo mostrar as categorias para adicionar usando $produto->getCategoria($categoria); . Porém usando set no lugar do get o código me mostra um erro na linha 61 da classe produto, onde justamente está o setCategoria(). Até agora foi o primeiro erro que achei :|

Opa mano, tudo bem?! Olha eu novamente por aqui!!

Então cara, baixei o seu projeto e estou fazendo algumas correções em relação a sintaxe apenas, notei que possuiam erros nas Models (Categoria/Produto), alguns erros no arquivo CriaProduto entre outros..

Percebi que você está usando um banco local, você poderia commitar o script .sql do banco que você está usando? Não se preocupe, usarei apenas para os testes..

Estou anotando todas as mudanças que estou realizando, e mantendo tambem o seu codigo original logo abaixo o meu corrigido, para que você possa analisar onde estavam os erros. No aguardo do script, abraço!

Boa Gabriel, não esquece de compartilhar aqui com a gente depois tá bem?

solução!

E aí Hugo, tudo numa boa?!

Então cara, como disse anteriormente baixei o seu projeto (criei um fork na verdade) para dar uma olhada no código e corrigir os eventuais erros. Solicitei uma copia do seu script, porém, como não obtive resposta não pude olhar/testar os seus arquivos de conexão. Enfim, fiz algumas correções nos arquivos. Criei um arquivo com o nome "ALTERAÇÕES" nele está descrito tudo que modifiquei e os respectivos arquivos..

Ah sim, não se preocupe que eu mantive TUDO que você fez previamente, todas as correções que fiz mantive seu código original (comentado) para que você possa ver a diferença entre os mesmos e também comentários sobre o que estava errado e alguns também explicando o porque o que fiz estava certo. No mais é isso, dê uma lida nos arquivos e qualquer coisa estamos aqui!!

Link do Fork: https://github.com/gabriel-sisjr/Projeto-de-php

Basicamente é isso, forte abraço e até a próxima!!!

Vlw mano. Desculpa não ter te enviado os dados de conexão tô meio ocupado esses dias.