我正在寻找oop来增强我的web开发知识。目前我有一个小问题。我已经创建了一个包含所有查询等的数据库类(fetch, count等),这只是允许查询或更新在其他类等中占用更少的空间。我遇到的问题是传递这个类,并使其在全球范围内可访问。我用了
global $db;
在类函数中,但我读到使用它是不好的做法。我也不想传递$db变量作为参数,如果我这样做,我将不得不改变很多我当前的类,它会更容易,如果我可以使$db在一个"好"的实践方式全局可用。
我可以提供我的数据库类,如果需要的话,它只是一个简单的类,通过构造启动连接的变量。
(第二题)
我也读到关于单例实例函数,在实现之前,我读到它也被认为是不好的做法。有什么东西应该取代它吗?
(我决定把这个类放在下面)
class Database {
private $host = 'localhost';
private $user = 'xxx';
private $pass = 'xxxx';
private $dbname = 'xxxxx';
private $dbh;
private $error;
public function __construct(){
// Set DSN
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
// Set options
$options = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING,
PDO::ATTR_EMULATE_PREPARES => false
);
// Create PDO Instance
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
}
public function fetch($sql, $param = "") {
$this->stmt = $this->dbh->prepare($sql);
if (empty($param)) {
$this->stmt->execute();
} else {
$this->stmt->execute($param);
}
return $this->stmt->fetch();
}
}
$db = new Database();
我试图完成的一个例子如下(用户资料页)
class User {
function set_user($input) {
if (is_numeric($input)) {
$this->user = $input;
} else {
$user = $db->fetch("SELECT userid FROM users WHERE url=:url", array(':url' => $input));
$this->user = $user['userid'];
}
}
}
您的方法的一个问题不是全局变量,而是DB连接是永久打开的。它并不总是好的。这是一种服务对象,让它全局可见并不是特别糟糕。
如果你不希望它是全局的,想要解决打开连接的问题,你可以很容易地在析构函数中关闭连接,删除全局变量,并在需要的地方创建/使用/删除DB。
另一种方法是不使用单例,而是使用所谓的服务类。使DB类不可实例化,而是定义服务方法(都是静态的)——打开、关闭、执行等等。那么DB客户端不应该创建DB对象,而只能访问静态方法。这种方法非常符合实际情况,因为DB-access被视为一种服务。