我正在尝试编写一个PDO包装器,但是我遇到了构造函数的一些问题。理想情况下,我想调用父的构造函数,但由于某种原因,这是行不通的。我尝试(测试)检查是否创建了一个新的PDO并且确实有效,这让我感到很困惑。
这是我的代码:
class db extends PDO {
private $dbconn;
public function __construct() {
$dsn = 'mysql:dbname=' . MYSQL_DB . ';host=' . MYSQL_HOST;
$user = MYSQL_USER;
$pw = MYSQL_PW;
try {
$this->dbconn = parent::__construct($dsn, $user, $pw);
$this->dbconn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $this->dbconn;
}
catch(PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();;
}
}
}
如果我将parent::
行替换为$this->dbconn = new PDO($dsn, $user, $pw);
我认为“正确/优雅”的方法是使用parent::
语法,所以我想知道为什么这不起作用/如何解决它。有人可以帮忙吗?
谢谢!
答案 0 :(得分:5)
这不是你如何使用构造函数,因为它们不返回任何东西。请尝试以下方法:
public function __construct() {
$dsn = 'mysql:dbname=' . MYSQL_DB . ';host=' . MYSQL_HOST;
$user = MYSQL_USER;
$pw = MYSQL_PW;
try {
parent::__construct($dsn, $user, $pw);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();;
}
}
注意:您可能仍会遇到问题,因为您的构造函数不接受与PDO构造函数相同的参数。 OOP的一个原则是等价,如Liskov Substitution Principle中所体现的,这意味着子类的协议(公共API)应该是其超类的严格超集。这一点很重要的原因是,如果子类的API与它继承的类所呈现的API不同,那么在所有情况下都不能用它来代替超类。
例如,您如何使用您的子类连接到PostgreSQL数据库或使用SQLite文件而不是使用mysql? PDO超类可以与所有三个以及其他数据库后端一起使用,因为您可以将DSN作为参数传递,但是您不能对子类执行此操作。
然而,所有这些都涉及到计算机科学的各个方面,并且正在逐渐偏离主题;)
答案 1 :(得分:5)
__construct()
没有返回值,当您扩展类时,您的自定义类是扩展类的类型。这意味着(在您的情况下)db
的对象也是PDO
的对象
完全
$dsn = 'mysql:dbname=' . MYSQL_DB . ';host=' . MYSQL_HOST;
$user = MYSQL_USER;
$pw = MYSQL_PW;
parent::__construct($dsn, $user, $pw);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
这就是你需要的整个构造函数
答案 2 :(得分:2)
此示例允许我简化软件中的连接字符串。
$db = new epdo('MyDataBase');
它还允许使用不同的服务器,用户名和密码,如果需要。希望这会有所帮助:
class epdo extends PDO {
public function __construct($dbname, $server='127.0.0.1', $username='usernamehere', $password='passwordhere') {
parent::__construct("mysql:host=$server;dbname=$dbname", $username, $password);
parent::setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
// error reporting (only show errors on localhost)
if( $_SERVER['SERVER_ADDR'] == '127.0.0.1') {
parent::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
} else {
parent::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
}
}
}