user3049124
user3049124

Reputation: 23

No error: PDO constructor was not called in

Good afternoon. I'm starting using the PDO yesterday, and I have some problem with this. I was creating extendet class, which doesn't work and I can't find the bug.

This is code of my helper class, for work witch PDO:

    class EPDO extends PDO {
  /** Some identificator of connection*/
  public $db;

  /**
   * Creating new PDO connections
   */     
  public function __construct($dbhost, $dbname, $dbuser = 'root', $dbpass = '', $dbtype = 'mysql') {
    $db = new PDO($dbtype . ':host=' . $dbhost . ';dbname=' . $dbname, $dbuser, $dbpass);
  } 

  /**
   * Insert into database with using transaction (if operation failed the changes go before)
   */     
  public function insert($statement) {
    $db->beginTransaction();

    $status = $db->exec($statement);
    if ($status) {
      $db->commit();  
    } else {
      $db->rollback();
    }
  } 
}

And this is the unfunctional code:

$stm = $db->prepare('SELECT id FROM `startups` WHERE id = :id');
$params = array(':id' => $child->id);
$ok = $stm->execute($params);
$row = $stm->fetch(PDO::FETCH_ASSOC);

Before this code I of course call the connections following way:

  require_once 'EPDO.php';

  try {
    $db = new EPDO('--server--', '--database--', '--user--', '--pass--');
  }
  catch (PDOException $err) {
    echo "Chyba spojeni: " . $err->getMessage();
  }

Thank you very much, and sorry for my english.

Upvotes: 2

Views: 10441

Answers (3)

Daniel W.
Daniel W.

Reputation: 32290

All these long answers, when the solution is so simple:

You have to use

$this->db = new PDO(...

instead of

$db = new PDO(...

Because when you hit

$db->commit();  

$db is empty = constructor not called.

The error message should be something like undefined method commit() on non-object. You also have to use

$this->db->commit();  

Use $this on every member and method accessed from inside the class

and so on...

Upvotes: 1

garbetjie
garbetjie

Reputation: 589

The problem is that you're extending the PDO class and overriding the constructor, all without calling the constructor.

Additionally, you're essentially creating two database connections every time you create a new object.

This should help resolve your issue, and reduce the connections created:

class EPDO extends PDO {
    /** Some identificator of connection*/
    public $db;

    /**
     * Creating new PDO connections
     */     
    public function __construct($dbhost, $dbname, $dbuser = 'root', $dbpass = '', $dbtype = 'mysql') {
        parent::__construct($dbtype . ':host=' . $dbhost . ';dbname=' . $dbname, $dbuser, $dbpass);
    } 

    /**
     * Insert into database with using transaction (if operation failed the changes go before)
     */     
    public function insert($statement) {
        $this->beginTransaction();
        $status = $this->exec($statement);
        if ($status) {
            $this->commit();  
        } else {
            $this->rollback();
        }
    }
}

Upvotes: 8

Bart Friederichs
Bart Friederichs

Reputation: 33511

Two problems: your design is wrong. You extend PDO, yet you create a new member object $db of type PDO inside. That won't work as you intend it. You'll have to call its super constructor.

public function __construct($dbhost, $dbname, $dbuser = 'root', $dbpass = '', $dbtype = 'mysql') {
      parent::__construct($dbtype . ':host=' . $dbhost . ';dbname=' . $dbname, $dbuser, $dbpass);
} 

In fact, this constructor isn't needed at all, you are just changing the parameters, creating confusion. So you can easily remove it, together with the $db attribute.

Second, to refer to class members and methods, use $this in PHP:

public function insert($statement) {
    $this->beginTransaction();

    $status = $this->exec($statement);
    if ($status) {
      $this->commit();  
    } else {
      $this->rollback();
    }
} 

Upvotes: 4

Related Questions