user1547410
user1547410

Reputation: 893

PDO and php - Call to a member function prepare() on a non-object

I started learning PDO and im still a bit of a PHP novice. Im doing a project to increase my knowledge but im stuck at the first hurdle.

Im getting this error: Call to a member function prepare() on a non-object on line 37 of this code. This is from database.class.php

<?php
// Include database class
include 'config.php';

class Database{
private $host      = DB_HOST;
private $user      = DB_USER;
private $pass      = DB_PASS;
private $dbname    = DB_NAME;

private $dbh;
private $error;

public function __construct(){
    // Set DSN
    $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
    // Set options
    $options = array(
        PDO::ATTR_PERSISTENT    => true,
        PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION
    );
    // Create a new PDO instanace
    try{
        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
    }
    // Catch any errors
    catch(PDOException $e){
        $this->error = $e->getMessage();
    }
}

// this variable holds the temporary statement
private $stmt;

// prepare our values to avoid SQL injection
public function query($query){
    $this->stmt = $this->dbh->prepare($query);
}

// use switch to select the appropiate type for the value been passed
// $param = placeholder name e.g username, $value = myusername
public function bind($param, $value, $type = null){
    if (is_null($type)) {
        switch (true) {
            case is_int($value):
                $type = PDO::PARAM_INT;
                break;
            case is_bool($value):
                $type = PDO::PARAM_BOOL;
                break;
            case is_null($value):
                $type = PDO::PARAM_NULL;
                break;
            default:
                $type = PDO::PARAM_STR;
        }
    }
// run the binding process
$this->stmt->bindValue($param, $value, $type);
}

// execute the prepared statement
public function execute(){
    return $this->stmt->execute();
}

// returns an array of the results, first we execute and then fetch the results
public function resultset(){
    $this->execute();
    return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
}

// same as resultset() except this returns a single result
public function result_single(){
    $this->execute();
    return $this->stmt->fetch(PDO::FETCH_ASSOC);
}

// count the number of rows from the previous delete, update or insert statement
public function rowCount(){
    return $this->stmt->rowCount();
}

// last insert id return the last id of the insert made, useful if you need to run a further
// query on the row you just inserted and need the id as the reference
public function lastInsertId(){
    return $this->dbh->lastInsertId();
}

// transactions allow you to rollback if a set of queries fail but it also allows ensures
// we avoid errors due to users interaction while half of the queries are still being written

// the following code begins a transaction
public function beginTransaction(){
    return $this->dbh->beginTransaction();
}

// end a transaction
public function endTransaction(){
    return $this->dbh->commit();
}

// rollback a transaction
public function cancelTransaction(){
    return $this->dbh->rollBack();
}

// this dumps the PDO information from the prepared statement for debug purposes
public function debugDumpParams(){
    return $this->stmt->debugDumpParams();
}

}

?>

Now the initial page im running this code in index.php

<?php

// Include database connection class
include 'includes/database.class.php';
include 'includes/bug.class.php';

$database = new Database;
$bugs = new Bugs;
$bugs->find_all_rows();

echo "<pre>";
print_r($rows);
echo "</pre>";

echo "Number of rows: " . $bugs->rowCount() . "<br />";


?>

And this is the page it would be running the find_all_rows function on which is the bugs.class.php file

<?php
class Bugs {

    public function find_all_rows() {
      return self::find_by_sql('SELECT * FROM tbl_priority');   
    }

    public function find_by_sql($sql="") {
      global $database;
      $database->query($sql);
      $rows = $database->resultset();

      return $rows;
    }
}
?>

Is there a debug tool that will help me trace these type of errors better or is it just a case im not familiar enough with PDO to spot an obvious mistake?

Upvotes: 1

Views: 3147

Answers (2)

Mandeep Gill
Mandeep Gill

Reputation: 390

Get same error and couldn't fix with code written above.

Here is easy fix as in your code this is the problem why PDO Sending Error :

public function __construct(){
    // Set DSN
    $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
    // Set options
    $options = array(
        PDO::ATTR_PERSISTENT    => true,
        PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION
    );
    // Create a new PDO instanace
    try{
        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
    }
    // Catch any errors
    catch(PDOException $e){
        $this->error = $e->getMessage();
    }
}

I am using PHP 5.5 and if someone have same error then he will need this

After $dns you need to add this where $this->dbname . ";";

Only this is how it will work for PHP 5.5 and Will not work with $this->dbname . "'";

public function __construct(){
    // Set DSN
    $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname . ";";
    // Set options
    $options = array(
        PDO::ATTR_PERSISTENT    => true,
        PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION
    );
    // Create a new PDO instanace
    try{
        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
    }
    // Catch any errors
    catch(PDOException $e){
        $this->error = $e->getMessage();
    }
}

Upvotes: 0

Neil Girardi
Neil Girardi

Reputation: 4923

@papaja hit the nail right on the head. Your PDO connection failed, thus you do not have a PDO object to run the prepare method on.

Off the top of my head, I think you are missing the end quote on the $dsn string. You probably want to add the following after $this->dbname and before the semi-colon:

. "'"

That's a single quote wrapped in double quotes. I use the following syntax to create the DSN string:

"mysql:host=$this->HOST;dbname=$this->DATABASE"

Anyway, create a test file so that you know exactly what the problem is. The test file should look like this:

class TestDatabase{

    private $host      = DB_HOST;
    private $user      = DB_USER;
    private $pass      = DB_PASS;
    private $dbname    = DB_NAME;
    private $dbh;


    public function __construct(){

        $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;

        $options = array(
            PDO::ATTR_PERSISTENT    => true,
            PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION
        );

        $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
    }
}

Note that we are not running the instantiation of the PDO object within a try catch block. While you would never ever do that in production, it will be useful for your test because it will throw a fatal exception containing all of the details of your connection.

Now instantiate the test class and proceed by debugging the errors you receive. Again, they will be more detailed than the previous error because it will be an uncaught PDO exception.

Upvotes: 2

Related Questions