下面我介绍了三个选项,用于在仅涉及单个连接时简化我的数据库访问(这通常是我工作的 Web 应用程序的情况)。
一般的想法是使数据库连接透明,以便它在我的脚本第一次执行查询时连接,然后保持连接直到脚本终止。
我想知道你认为哪一个是最好的,为什么。我不知道这些可能适合的任何设计模式的名称,很抱歉没有使用它们。如果使用 PHP5有更好的方法,请分享。
简单介绍一下:有一个包含查询方法的DB_Connection 类。这是一个不受我控制的第三方类,为了本示例的目的,我已经简化了它的接口。在每个选项中,我还为虚构的数据库“项目”表提供了一个示例模型,以提供一些上下文。
选项 3 是为我提供了我最喜欢的界面的选项,但不幸的是我认为它不实用。
我已经在下面的评论块中描述了每种方法的优缺点(我可以看到)。
目前我倾向于选项 1,因为负担放在了我的数据库包装类而不是模型上。
所有评论表示赞赏!
注意:出于某种原因,堆栈溢出预览显示的是编码的 HTML 实体,而不是下划线。如果帖子是这样通过的,请考虑到这一点。
<?php
/**
* This is the 3rd-party DB interface I'm trying to wrap.
* I've simplified the interface to one method for this example.
*
* This class is used in each option below.
*/
class DB_Connection {
public function &query($sql) { }
}
/**
* OPTION 1
*
* Cons: Have to wrap every public DB_Connection method.
* Pros: The model code is simple.
*/
class DB {
private static $connection;
private static function &getConnection() {
if (!self::$connection) {
self::$connection = new DB_Connection();
}
return self::$connection;
}
public static function &query($sql) {
$dbh = self::getConnection();
return $dbh->query($sql);
}
}
class Item {
public static function &getList() {
return DB::query("SELECT * FROM items");
}
}
/**
* OPTION 2
*
* Pros: Don't have to wrap every DB_Connection function like in Option 1
* Cons: Every function in the model is responsible for checking the connection
*/
class DB {
protected static $connection = null;
public function connect() {
self::$connection = new DB_Connection();
}
}
class Item extends DB {
public static function &getList() {
if (!self::$connection) $this->connect();
return self::$connection->query("SELECT * FROM items");
}
}
/**
* OPTION 3
*
* Use magic methods
*
* Pros: Simple model code AND don't have to reimplement the DB_Connection interface
* Cons: __callStatic requires PHP 5.3.0 and its args can't be passed-by-reference.
*/
class DB {
private static $connection = null;
public static function &getConnection() {
if (!self::$connection) {
self::$connection = new DB_Connection();
}
return self::$connection;
}
public static function __callStatic($name, $args) {
if (in_array($name, get_class_methods('DB_Connection'))) {
return call_user_func_array(
array(self::getConnection(), $name), $args);
}
}
}