突然之间,一段时间运行良好的脚本停止了,没有错误。我已将其固定到__contruct方法,但无法理解为什么会发生这种情况。简化版的代码......
<?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
}
}
?>
PDO构造函数独立工作,实际上我在ex1构造函数中的任何内容似乎都没有运行,日志中没有错误(设置为E_ALL和E_STRICT)。
有什么想法吗?
答案 0 :(得分:4)
简单的继承规则(就构造函数而言)如下:
基本上,这意味着,应用于您的代码,应该自动调用父构造函数。你说构造函数没有被调用,所以你可能在子类中定义了一个构造函数,在这种情况下,简单地添加这个语句:
parent::__construct();
几个例子
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();
这将回显123
,因为Foo::__construct()
会自动调用。但是,如果我们稍微更改Bar
,则行为会发生变化:
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
因此val
属性未被设置。但是,这是一个简单的解决方法:
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
总而言之,将属性设置为PDO
的实例并不是最好的创意。查看依赖注入,谷歌控制反转以及所有这些流行语。
另一种方法是使用延迟加载的getter:
class Foo
{
$this->db = null;
protected function getDb()
{
if ($this->db === null)
$this->db = new PDO();//create when needed
return $this->db;
}
}
这样,当依赖于该连接的代码调用getDb
方法时,将在最后一刻创建数据库连接...
答案 1 :(得分:2)
如果你的ex2
类有自己的构造函数,你应该从中调用父类:
class ex2 extends ex1 {
function __contruct() {
/* ex2::__construct() code here */
parent::__construct();
}
function somefunc() {
is_object($this->dbh);
}
}
你也有错字:
somefunc() {}
应该是:
function somefunc() {}