问题
Is it possible to keep all my database related configuration (hostnames, usernames, passwords, and databases) as well as the function to connect to and select the correct database in a separate class?
I tried something like this:
class Database
{
var $config = array(
'username' => 'someuser',
'password' => 'somepassword',
'hostname' => 'some_remote_host',
'database' => 'a_database'
);
function __construct() {
$this->connect();
}
function connect() {
$db = $this->config;
$conn = mysql_connect($db['hostname'], $db['username'], $db['password']);
if(!$conn) {
die("Cannot connect to database server");
}
if(!mysql_select_db($db['database'])) {
die("Cannot select database");
}
}
}
And then in another class I would use in the classes __construct function:
require_once('database.php');
var $db_conn = new Database();
But this doesnt save the connection, it ends up defaulting to the servers local db connection. Or do I have to do the database commands everytime before I execute some database commands?
回答1:
I modified your class to work as you seem to be expecting it to:
<?php
class Database
{
var $conn = null;
var $config = array(
'username' => 'someuser',
'password' => 'somepassword',
'hostname' => 'some_remote_host',
'database' => 'a_database'
);
function __construct() {
$this->connect();
}
function connect() {
if (is_null($this->conn)) {
$db = $this->config;
$this->conn = mysql_connect($db['hostname'], $db['username'], $db['password']);
if(!$this->conn) {
die("Cannot connect to database server");
}
if(!mysql_select_db($db['database'])) {
die("Cannot select database");
}
}
return $this->conn;
}
}
Usage:
$db = new Database();
$conn = $db->connect();
Note that you can call connect() as many times as you like and it will use the current connection, or create one if it doesn't exist. This is a good thing.
Also, note that each time you instantiate a Database object (using new) you will be creating a new connection to the database. I suggest you look into implementing your Database class as a Singleton or storing it in a Registry for global access.
You can also do it the dirty way and shove it in $GLOBALS.
Edit
I took the liberty of modifying your class to implement the Singleton pattern, and follow the PHP5 OOP conventions.
<?php
class Database
{
protected static $_instance = null;
protected $_conn = null;
protected $_config = array(
'username' => 'someuser',
'password' => 'somepassword',
'hostname' => 'some_remote_host',
'database' => 'a_database'
);
protected function __construct() {
}
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
public function getConnection() {
if (is_null($this->_conn)) {
$db = $this->_config;
$this->_conn = mysql_connect($db['hostname'], $db['username'], $db['password']);
if(!$this->_conn) {
die("Cannot connect to database server");
}
if(!mysql_select_db($db['database'])) {
die("Cannot select database");
}
}
return $this->_conn;
}
public function query($query) {
$conn = $this->getConnection();
return mysql_query($query, $conn);
}
}
Usage:
$res = Database::getInstance()->query("SELECT * FROM foo;");
or
$db = Database::getInstance();
$db->query("UPDATE foo");
$db->query("DELETE FROM foo");
回答2:
You can certainly keep your connection info in a separate file.
Just save your connection object - $conn in your connect() function - in a class variable. You'll then be able to reuse it across calls.
回答3:
In your method connect() $conn is only a local variable that only exists in the scope of that method. As soon as the method returns there will be no (other) reference to the connection resource and it will be collected/disposed. You'll need at least
$this->conn = mysql_connect(...)
回答4:
Here comes the singleton with PDO example. Thanks to @hodobave
<?php
/**
* DB Connection class
* Singleton pattern
* An single instance of DB connection is created
**/
class Db{
protected static $_instance = null;
protected $_conn;
protected $_config = [
'username' => 'root',
'password' => '',
'hostname' => 'localhost',
'database' => 'news',
];
protected function __construct(){
}
public function getInstance(){
if(null === self::$_instance){
self::$_instance = new self();
}
return self::$_instance;
}
public function getConnection(){
if(is_null($this->_conn)){
//connect here
$db = $this->_config;
$dsn = "mysql:host={$db['hostname']};dbname={$db['database']}";
$this->_conn = new PDO($dsn, $db['username'], $db['password']);
}
return $this->_conn;
}
public function query($sql){
$args = func_get_args();
array_shift($args);
$statement = $this->getConnection()->prepare($sql);
$statement->execute($args);
return $statement->fetchAll(PDO::FETCH_OBJ);
}
}
$res = Db::getInstance();
$users = $res->query("SELECT * FROM `user` WHERE id=?",1);
print_r($users);
?>
来源:https://stackoverflow.com/questions/1202712/mysql-database-config-in-a-separate-class