希望我不会太晚,但您可以尝试使用单例上下文对象,这将允许全局访问您的对象并避免使用静态类。
您需要做的就是在Application::bootstrap 方法中创建您需要的对象并将它们分配给上下文。
至于模型,我不会直接从数据库继承,而是像下面的模型类那样使用组合。
编辑:我对 PHP 有点生疏了,但是上次我检查了 PDO 和 Mysqli 有非常不同的实现,所以我添加了
一个通用的数据库接口和两个半实现,它将允许从一个扩展切换到另一个,而不会用无用的条件污染代码。
上下文.php
<?php
namespace Core;
/**
* Context singleton class.
* Contains 'global instances' reusable by your application
*/
class Context {
private static $instance = null;
private $config;
private $db;
public static function getInstance() {
if (null == $instance) {
$instance = new Context();
}
return $instance;
}
private function __construct() {
}
public function getConfig() {
return $this->config;
}
public function setConfig(Config $config) {
$this->config = $config;
}
public function getDatabase() {
return $this->db;
}
public function setDatabase(Database $db) {
$this->db = $db;
}
}
?>
配置.php
<?php
namespace Core;
/**
* Config class, Since you didn't post the implementation
* I took the liberty to implement it as ArrayObject
*/
class Config extends ArrayObject {
public function __construct(array $configurationArray) {
parent::__construct($configurationArray, self::ARRAY_AS_PROPS);
}
}
?>
数据库.php
<?php
namespace Core;
/**
* Database interface.
*
* Provides a common interface for different PHP extensions
*/
interface Database {
public function connect();
public function diconnect();
public function getConnection();
public function query($sql);
public function countRows();
public function fetchRows();
// Add other useful wrapper methods here...
}
?>
MysqliAdapter.php
<?php
namespace Core;
use \mysqli;
/**
* Mysqli Database Adapter
*
* Wraps Mysqli extension
*/
class MysqliAdapter implements Database {
private $connection;
public function connect() {
$config = Context::getInstance()->getConfig();
$this->connection = new mysqli($config['database']['dbhost'], $config['database']['dbuser'], $config['database']['dbpass'], $config['database']['dbname']);
}
public function diconnect() {
// Implement mysqli disconnection here
}
public function getConnection() {
return $this->connection;
}
public function query($sql) {
// Implement mysqli query here
}
public function countRows() {
// Implement mysqli count rows here
}
public function fetchRows() {
// Implement mysqli fetch rows here
}
}
?>
PDOAdapter.php
<?php
namespace Core;
use \PDO;
/**
* PDO Database Adapter
*
* Wraps PDO extension
*/
class PDOAdapter implements Database {
private $connection;
public function connect() {
$config = Context::getInstance()->getConfig();
$dsn = 'mysql:host='. $config['database']['dbhost'].';dbname='.$config['database']['dbname'];
$this->connection = new PDO($dsn, $config['database']['dbuser'], $config['database']['dbpass']);
}
public function diconnect() {
// Implement PDO disconnection here
}
public function getConnection() {
return $this->connection;
}
public function query($sql) {
// Implement PDO query here
}
public function countRows() {
// Implement PDO count rows here
}
public function fetchRows() {
// Implement PDO fetch rows here
}
}
?>
模型.php
<?php
namespace Core;
/**
* Abstract model, holds a database instance, it's not necessary since you can access it
* from the Context but this way it will be inherited by subclasses
*/
abstract class Model {
protected $db;
public function __construct() {
// Assign Database object from the context
$this->db = Context::getInstance()->getDatabase();
}
// Model methods if any....
}
?>
应用程序.php
<?php
namespace Core;
/**
* Application class.
*/
class Application {
public static function bootstrap(array $configurationArray) {
// Initialize and put configuration object into the Context
$config = new Config($configurationArray);
Context::getInstance()->setConfig( $config );
// Connect to the database using the right adapter.
// Remember to set the 'dbdriver' setting or $db will be undefined
switch ($config['database']['dbdriver']) {
case 'MySQLi':
$db = new MysqliAdapter();
break;
case 'PDO':
$db = new PDOAdapter();
break;
}
$db->connect();
Context::getInstance()->setDatabase( $db );
}
}
?>
config.php
<?php
/**
* Configuration array
*/
return array(
'database' => array(
'dbdriver' => '...',
'dbhost' => '...',
'dbuser' => '...',
'dbpass' => '...',
'dbname' => '...'
)
);
?>
index.php
<?php
use Core\Application;
// Not a very good way, but it should serve you
// well enough during development
$configurationArray = require_once 'config.php';
// Start application
Application::bootstrap( $configurationArray );
?>
我没有测试代码,但应该足以给你这个想法
干杯