All of a sudden, a script that was working fine for quite some time has stopped, with no error. I've pinned it down to the __contruct method but cannot understand why it's happening. Simplified version of the code....
<?php
class ex1 {
protected $dbh;
function __construct(){
$this->dbh = new PDO('mysql:host=localhost;dbname=db', 'user', 'pw', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
}
}
?>
<?php
include('ex1.class.php');
class ex2 extends ex1 {
somefunc(){
is_object($this->dbh); // = FALSE
}
}
?>
The PDO constructor works on its own, in fact nothing I put in the ex1 constructor seems to run and no errors in the logs (set to E_ALL & E_STRICT).
Any ideas?
If, your ex2
class has a constructor on it's own, you should call the parent one from it:
class ex2 extends ex1 {
function __contruct() {
/* ex2::__construct() code here */
parent::__construct();
}
function somefunc() {
is_object($this->dbh);
}
}
Also you have a typo:
somefunc() {}
should be:
function somefunc() {}
The simple rules of inheritance (in terms of constructors) are as follows:
Basically, that means that, applied to your code, the parent constructor should be called automatically. You say the constructor is not being called, so you probably defined a constructor in the child class, in which case, simple add this statement:
parent::__construct();
A couple of examples
class Foo
{
protected $val = null;
public function __construct()
{
$this->val = 123;
}
}
class Bar extends Foo
{
public function test()
{
return $this->val;
}
}
$b = new Bar();
echo $b->test();
This will echo 123
, because Foo::__construct()
is called automatically. However, if we change Bar
a bit, then the behaviour changes:
class Bar extends Foo
{
protected $another = null;
public function __construct()
{
$this->another = __METHOD__;
}
public function test()
{
return $this->val;
}
}
$b = new Bar();
var_dump($b->test());//null
So the val
property isn't being set. A simple fix, though:
class Bar extends Foo
{
protected $another = null;
public function __construct()
{
$this->another = __METHOD__;
parent::__construct();//call here, explicitly
}
public function test()
{
return $this->val;
}
public function getMethod()
{
return $this->another;
}
}
$b = new Bar();
var_dump($b->test());//123
echo $b->getMethod();//echoes Bar::__construct
All in all, setting properties to an instance of PDO
isn't considered the best of ideas. Check out dependency injection, google inversion of control and all those buzz-words.
An alternative approach would be to use lazy-loading getters:
class Foo
{
$this->db = null;
protected function getDb()
{
if ($this->db === null)
$this->db = new PDO();//create when needed
return $this->db;
}
}
This way, the DB connection will be created at the last possible moment, when the code that relies on that connection calls the getDb
method...