Fatal error: Call to a Member Function prepare() on a non-object

Asked

Viewed 1,145 times

0

I am creating a class to perform querys in the bank, but am having the following error when I have use Prepared statements:

Fatal error: Call to a Member Function prepare() on a non-object in C: xampp htdocs Minhasfuncoes php model.php on line 13

Where can I be missing? I thought I was the builder, but apparently it’s not.

Index:

<?php
require_once 'model.php';
 $conn = new model("mysql","localhost", "teocratico", "UTF8","root","");
 $conn->consulta("descricao","desafios");
?>

Class:

 <?php
    class model {
      private $conexao;

      public function __construct ($db, $host, $dbname, $charset, $usuario, $senha){
        try{
          $this->conexao = new PDO ("$db:host=$host; dbname=$dbname; charset=$charset","$usuario","$senha");
        } catch (PDOException $erro){
            return $erro->getmessage();
        }
      }
      public function consulta ($campos, $tabela){
        $this->conexao->prepare("SELECT :campos FROM :tabela"); //erro nessa linha
        $this->conexao->BindParam(':campos', $campos);
        $this->conexao->BindParam(':tabela', $tabela);
        $this->conexao->execute();
        $resultado = $this->conexao->fetchAll(PDO::FETCH_ASSOC);
        echo $resultado;
      }
    }

    ?>
  • Before line 13, knife: echo $campos." - ".$tabela; die(); See what brings in fields and table.

1 answer

2


Using Try/catch inside the constructor no longer looks good and even more use return in it, this will not work, it is better to use the Try/catch outside the class, so at least it will have a sensible use for them, since using a Try/catch just to check the PDO and not stop the rest of what should be part of the "same" block does not have much sense

So to explain better, I believe that the problem is occurring in the connection and how you used Try/catch does not emit anything and does not finish the script and as I said return "does not work" on __construct, then you try to use the method consulta, but the variable $this->conexao didn’t go through the try by some fault in the call of new PDO, then she was still NULL.

you also passed the bindParam on the connection instead of using on the prepare and in the execute:

$this->conexao->prepare("SELECT :campos FROM :tabela"); //erro nessa linha
$this->conexao->BindParam(':campos', $campos);
$this->conexao->BindParam(':tabela', $tabela);

This should be it:

$prepare = $this->conexao->prepare("SELECT :campos FROM :tabela"); //erro nessa linha
$prepare->BindParam(...);
$prepare->BindParam(...);

Another problem that Rray pointed out to me was the use of the parameters for the FROM and columns, there’s no way this works the way you did, the bindParam and bindValue function as character escapers, actually the parameters after processed would look something like:

SELECT 'id, nome, senha' FROM 'minhatabela'

That is, query will not search minhatabela on the bench, he’ll look 'minhatabela' with the included apostrophes and instead of looking for the 3 columns it will look for generate a column with the name id, nome, senha, like it’s all one thing.

I suggest we move on to this:

<?php
class model {
  private $conexao;

  public function __construct ($db, $host, $dbname, $charset, $usuario, $senha){
        $this->conexao = new PDO ("$db:host=$host; dbname=$dbname; charset=$charset","$usuario","$senha");
  }

  public function consulta (array $campos, $tabela){
    $prepare = $this->conexao->prepare("SELECT ' . $campos . ' FROM " . $tabela);

    $prepare->execute();

    $resultado = $prepare->fetchAll(PDO::FETCH_ASSOC);
    print_r($resultado);
  }
}

And on the call:

require_once 'model.php';

try{
    $conn = new model("mysql","localhost", "teocratico", "UTF8","root","");
    $conn->consulta("descricao","desafios");
} catch (PDOException $erro){
    echo $erro->getmessage();
}

Of course you should not pass access to control $campos and $tabela end user by GET and POST, otherwise use the bindParam remembering that it always "escapes" the characters and "adds the apostrophes" in the processing

  • 2

    I believe what bind of this (question) code does not work, has in the list of fields and in the table name.

  • That’s right, SELECT :campos FROM :tabela

  • @rray opa, missing correct some details, hasty edition :p

  • Haha, the first comment from me got really bad. I meant that Binds apply only in values (except some hacks) and not in table names or list of fields. The correction of the prepare() is also important.

  • @rray I tested and entedi, I had forgotten the "escape" of the instructions prepared, edited and thank you ;)

  • I’m performing some tests, I give the feedback if it worked. Thanks from now :)

  • It worked, but the execute, how do I implement the bindParam this way then? Or how do I handle to avoid Sqlinjection? One time the data sent by the user will arrive in the query :/

  • @Tiagosilveyou really want to pass columns and control tables to the end user?

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.