Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Maykel-ctba

Iniciando com PHP PDO e OO - Erro na função "prepare"

Recommended Posts

Fala galera,

 

Em um tópico criado ontem, vi que PHP PDO é um pouco mais complexo do que imaginei e acima do meu conhecimento atual. Então, estou correndo atrás pra aprender com um projeto um pouco mais simples.

 

Gostaria de dicas de como posso melhorar meu código, se estou fazendo certo ou errado, se possível!

 

O que estou fazendo hoje:

  • Uma classe que gerencie Querys (Inserções, Edições, Remoções e Listagens de itens do banco de dados) - Por enquanto fiz apenas a parte de inserção, pra aprender.
  • Uma classe que gerencie Categorias (utilizando a classe de Querys acima).

 

 

Porém, no meu primeiro teste, recebi o seguinte erro:

 

Fatal error: Call to a member function prepare() on a non-object in /Applications/XAMPP/xamppfiles/htdocs/common/class/categoria.class.php on line 266

 

A linha 266 está dentro da classe Main (a que gerencia Querys):

$query = $pdo->prepare("INSERT INTO ".$this->tables." (".$column.") VALUES(".$prepareValue.")");

 

----------------------------

 

Meu arquivo está dividido em 4 partes - Caso seja necessário para análise, seguem os trechos:

 

Parte #1: Conexão com o banco

define('DB_HOST','localhost');
define('DB_BASE','8ight');
define('DB_USER','root');
define('DB_PASS','');

$connection = 'mysql: host='.DB_HOST.'; dbname='.DB_BASE;	

try
{
    $connect = new PDO($connection, DB_USER, DB_PASS);
    $connect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOexception $error)
{
    "Connection Error. Verify your database connection.";
}

 

Parte #2: Criação da classe Main - A que gerencia os Querys (Insert/update/delete/select)

// * Classe de gerenciamento de Querys
class Main
{
    // * Visibilidade
    protected $tables;
    protected $columns;
    protected $values;
    protected $condition;
    protected $order;
    protected $limit;
    protected $group;
    protected $total;
    
    // * Construtores
    function __construct()
    {
        $this->tables = null;
        $this->columns = null;
        $this->values = null;
        $this->condition = null;
        $this->order = null;
        $this->limit = null;
        $this->group = null;
        $this->total = 0;
    }
    
    // * Atribuição de valores
    function setTables($value)
    {
        $this->tables = $value;
    }
    
    function setColumns($value)
    {
        $this->columns = $value;
    }
    
    function setValues($value)
    {
        $this->values = $value;
    }
    
    function setCondition($value)
    {
        $this->condition = $value;
    }
    
    function setOrder($value)
    {
        $this->order = $value;
    }
    
    function setLimit($value)
    {
        $this->limit = $value;
    }
    
    function setGroup($value)
    {
        $this->group = $value;
    }
    
    function setTotal($value)
    {
        $this->total = $value;
    }
    
    function getTables()
    {
        return $this->tables;
    }
    
    function getColumns()
    {
        return $this->columns;
    }
    
    function getValues()
    {
        return $this->values;
    }
    
    function getCondition()
    {
        return $this->condition;
    }
    
    function getOrder()
    {
        return $this->order;
    }
    
    function getLimit()
    {
        return $this->order;
    }
    
    function getTotal()
    {
        return $this->order;
    }
    
    // * Funções de manipulação
    // * Função de inserção ao banco de dados
    function Insert()
    {
        // * Conta as tabelas a serem utilizadas
        if (count($this->tables) > 1)
        {
            $error = true;
        }
        
        // * Conta as colunas a serem utilizadas
        if (count($this->columns) > 0)
        {
            for ($i = 0; $i < count($this->columns); $i++)
            {
                if (empty($column)) // * Se é o primeiro campo
                {
                    $column = trim($this->columns[$i]);
                }
                else // * Se for do segundo pra frente, só concatena
                {
                    $campo .= ", ".trim($this->columns[$i]);
                }
            }
        }
        else // * Caso não tenham columns, retorna erro
        {
            $error = true;
        }
        
        // * Conta os valores a serem utilizados
        if (count($this->values) > 0)
        {
            for ($i = 0; $i < count($this->values); $i++)
            {
                if (empty($value)) // * Se é o primeiro valor
                {
                    $value = "'".trim($this->values[$i])."'";
                    $prepareValue = "?";
                }
                else // * Se for do segundo pra frente, só concatena
                {
                    $value .= ", '".trim($this->values[$i])."'";
                    $prepareValue .= ", ?";
                }
            }
        }
        else // * Caso não tenham values, retorna erro
        {
            $error = true;
        }
        
        // * Inicia a montagem da query
        // * Verifica se não existiram erros
        if (!$error)
        {
            try
            {
                $query = $pdo->prepare("INSERT INTO ".$this->tables." (".$column.") VALUES(".$prepareValue.")");
                
                for($i = 0; $i < count($this->values); $i++)
                {
                    $query->bindParam($i,$this->values[$i]);
                }
                
                $query->execute();
                
            }
            catch (Exception $e)
            {
                $result = 0;
            }
            
            return $result;
            
        }
        else // * Caso tenha erro
        {
            return $error;
        }
    }
}

 

Parte #3: Criação da classe Categoria

// * Classe de gerenciamento de categorias
class Categoria
{
    // * Visibilidade
    private $catId;
    private $catTitulo;
    private $catDataCadastro;
    private $catAtivo;
    private $catExcluido;
    
    // * Construtores
    function __construct() 
    {
        $this->catId = 0;
        $this->catTitulo = "";
        $this->catDataCadastro = "";
        $this->catAtivo = "";
        $this->catExcluido = "";	
    }
    
    // * Atribuição de valores
    function ID($value = null)
    {
        if (!is_null($value)) { $this->catId = $value; }
        else { return $this->catId; }
    }
    
    function Titulo($value = null)
    {
        if (!is_null($value)) { $this->catTitulo = $value; }
        else { return $this->catTitulo; }
    }
    
    function DataCadastro($value = null)
    {
        if (!is_null($value)) { $this->catDataCadastro = $value; }
        else { return $this->catDataCadastro; }
    }
    
    function Ativo($value = null)
    {
        if (!is_null($value)) { $this->catAtivo = $value; }
        else { return $this->catAtivo; }
    }
    
    function Excluido($value = null)
    {
        if (!is_null($value)) { $this->catExcluido = $value; }
        else { return $this->catExcluido; }
    }
    
    // * Funções de manipulação
    function Cadastrar()
    {
        $tabelas = array();
        $colunas = array();
        $valores = array();
        
        $tabelas[]	= "sys_categoria";
        
        $colunas[] 	= "catTitulo";
        $colunas[] 	= "catDataCadastro";
        $colunas[]	= "catAtivo";
        
        $valores[]	= $this->catTitulo;
        $valores[]	= date("Y-m-d H:i:s");
        $valores[]	= $this->catAtivo;
        
        $query = new Main();
        
        $query->setTables($tabelas);
        $query->setColumns($colunas);
        $query->setValues($valores);
        
        if ($resultado = $query->Insert())
        {
            return $query->GetLastID();
        }
        else
        {
            return 0;	
        }
    }
}

 

Parte #4: Finalmente, o uso prático

$objRegistro = new Categoria();
$objRegistro->Titulo("Teste de cadastro");
$objRegistro->Ativo("S");

$resultadoCadastro = $objRegistro->Cadastrar();

if(!empty($resultadoCadastro))
{
    echo "Registro inserido! ID: ".$resultadoCadastro;
}
else
{
    echo "Erro no cadastro";	
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

$pdo vem da onde? não seria $connect no lugar?

vc n precisa colocar entre aspas simples os itens do value, o pdo ja faz isso.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Uma coisa que vi, iniciei o objeto PDO fora das classes... será que é por isso que ele não identifica dentro delas o uso?

 

Se você não injetar a dependência de PDO, não irá funcionar de qualquer jeito.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não é $pdo e sim $connect afinal você está criando ele nessa variavel:

 

$connect = new PDO($connection, DB_USER, DB_PASS);

Se você quer realmente concatenar valores concatene em uma variavel separada:

$sql = "INSERT INTO ".$this->tables." (".$column.") VALUES(".$prepareValue.")";
$query = $pdo->prepare(sql);

//lembrando que value precisa de aspas simples
$sql = "INSERT INTO ".$this->tables." (".$column.") VALUES('".$prepareValue."')";

Sendo que se quer trabalhar com PDO use BindValue:

 


$query = $pdo->prepare("INSERT INTO ".$this->tables." (:coluna) VALUES(:valor)");
$query->bindValue(':coluna','nomedacoluna',PDO::PARAM_STR);
$query->bindValue(':valor','OvalorAqui',PDO::PARAM_STR);
$query->execute();

Um abraço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@Gabriel eu movi o início do objeto para dentro do try, e o erro desapareceu.

 

@srnalim Eu renomeei o $connect para $pdo, mantendo um padrão. Aparentemente está OK... fiz alguns outros ajustes que vi, e a minha consulta está imprimindo assim:

 

INSERT INTO sys_categoria (catTitulo, catDataCadastro, catAtivo) VALUES(?, ?, ?)

 

Mas ele não está entrando no For (dentro do try da montagem da query), ele não está atribuindo os valores...

 

function Insert()
{
    // * Conta as tabelas a serem utilizadas
    if (count($this->tables) > 1)
    {
        $error = true;
    }
    
    // * Conta as colunas a serem utilizadas
    if (count($this->columns) > 0)
    {
        for ($i = 0; $i < count($this->columns); $i++)
        {
            if (empty($column)) // * Se é o primeiro campo
            {
                $column = trim($this->columns[$i]);
            }
            else // * Se for do segundo pra frente, só concatena
            {
                $column .= ", ".trim($this->columns[$i]);
            }
        }
    }
    else // * Caso não tenham columns, retorna erro
    {
        $error = true;
    }
    
    // * Conta os valores a serem utilizados
    if (count($this->values) > 0)
    {
        for ($i = 0; $i < count($this->values); $i++)
        {
            if (empty($value)) // * Se é o primeiro valor
            {
                $value = "'".trim($this->values[$i])."'";
                $prepareValue = "?";
            }
            else // * Se for do segundo pra frente, só concatena
            {
                $value .= ", '".trim($this->values[$i])."'";
                $prepareValue .= ", ?";
            }
        }
    }
    else // * Caso não tenham values, retorna erro
    {
        $error = true;
    }
    
    // * Inicia a montagem da query
    // * Verifica se não existiram erros
    if (!$error)
    {
        try
        {
            $queryMontada = "INSERT INTO ".$this->tables[0]." (".$column.") VALUES(".$prepareValue.")";
            
            $pdo = new PDO($connection, DB_USER, DB_PASS);
            $query = $pdo->prepare($queryMontada);
            
            for($i = 0; $i < count($this->values); $i++) // * Parece que não entra aqui...
            {
                $query->bindParam($i,$this->values[$i]);
            }
            
            $query->execute();
            
            $result = $pdo->lastInsertId();
            
        }
        catch (Exception $e)
        {
            $result = 0;
            $error = $e;
        }
        
        return $result;
        
    }
    else // * Caso tenha erro
    {
        return $error;
    }
}

 

Estou seguindo este tutorial como lógica:

http://www.devmedia.com.br/introducao-ao-php-pdo/24973

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu reforço que você deve injetar a dependência da PDO, e não instanciá-la dentro do método. No seu caso, o nível de acoplamento torna-se muito alto, o que é ruim para o uso e manutenção do código.

Compartilhar este post


Link para o post
Compartilhar em outros sites

#6 Se você estiver usando PDO, e concatenar os valores separadamente, não usufluirá de uma das propostas de prepared statements que é a segurança contra SQL Injection. Há um post antigo que mostrar como concatenar de forma a proteger a consulta.

 

http://forum.imasters.com.br/topic/472433-pdo-consulta-com-in/?p=1875979



Leia o artigo abaixo, vai lhe dar uma boa noção sobre dois assuntos importantes:
Inversão de Controle x Injeção de Dependência

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.