我正在尝试学习PHP OOP,并对如何在我的项目中使用全局数据库类进行了一些研究。从我所看到的,最合适的模式是一个单例,它可以确保始终只存在一个数据库连接。然而,由于这是我第一次使用Singleton模式,我不确定我是否做得对。
这是一个合适的单身人士吗?此代码是否仅确保一个数据库连接?有什么办法可以测试吗? (学会钓鱼的人,他将在余生中获得食物......)
我使用redbean作为我的ORM,这是我如何明确地设置它:
require_once PLUGINPATH.'rb.php';
$redbean= R::setup("mysql:host=192.168.1.1;dbname=myDatabase",'username','password');
我已根据this source创建了以下脚本,作为我自己的单例数据库类;
class database {
private $connection = null;
private function __construct(){
require_once PLUGINPATH.'rb.php';
$this->connection = R::setup("mysql:host=192.168.1.1;dbname=myDatabase",'username','password');
}
public static function get() {
static $db = null;
if ( $db === null )
$db = new database();
return $db;
}
public function connection() {
return $this->connection;
}
}
谢谢!
答案 0 :(得分:6)
实例变量必须是类的静态成员。我没有测试过这段代码,但它应该可行。连接也应该是静态的。使用此代码,您将拥有一个数据库类实例和一个连接实例。可以在没有静态连接的情况下执行此操作,但将其设置为静态将确保只有一个连接实例。我还将类的文字名称更改为php magic constants。这使您的代码更易于维护。如果您在路上更改班级名称,则无需在代码中查找旧班级名称的所有文字实例。现在看起来似乎有些过分,但相信我,当你在越来越复杂的项目上工作时,你会欣赏它的价值。
class database {
private static $connection = null;
private static $db;
private function __construct(){
require_once PLUGINPATH.'rb.php';
self::$connection = R::setup("mysql:host=192.168.1.1;dbname=myDatabase",'username','password');
}
public static function get() {
if ( !(self::$db instanceof __CLASS__) ) {
$klass = __CLASS__; // have to set this to a var, cant use the constant with "new"
self::$db = new $klass();
}
return self::$db;
}
public function connection() {
return self::$connection;
}
}
答案 1 :(得分:2)
你的单身几乎是正确的。
私人成员(没有双关语)$connection
也需要是静态的。您也可以使用以下内容:
class database {
private static $instance = NULL;
protected $conn;
private function __construct() {
$this->conn = mysql_connect( ... );
}
public static function init() {
if (NULL !== self::$instance)
throw new SingletonException();
self::$instance = new database();
}
public static function get_handle() {
if (NULL === self::$instance)
; // error handling here
return self::$instance->conn;
}
}