我正在构建一个Query Builder(用于练习),为此我需要一个数据库连接,所以我创建了这个类:
/**
* Represents a mysql server connection
*/
class MySQLServerConnection implements Connection
{
/**
* @var null|PDO
*/
private $instance = null;
/**
* @var string The host the Connection should connect to
*/
private $host;
/**
* @var string The username to login into the name
*/
private $username;
/**
* @var string The password to login into the name
*/
private $password;
/**
* @var array
*/
private $attributes = [];
/**
* @param float $host
* @param string $username
* @param string $password
* @param array $attributes
*/
public final function __construct ($host, $username, $password, $attributes = []) {
$this->host = $host;
$this->username = $username;
$this->password = $password;
$this->attributes = $attributes;
}
/**
* @throws ConnectionException
*/
public final function initialize () {
if ($this->isInitialized()) {
throw new ConnectionException("Database connection isnt open yet.");
}
$this->instance = new PDO("mysql:host=$this->host;", $this->username, $this->password);
}
/**
* @return bool
*/
public function isInitialized () {
return $this->instance !== null;
}
/**
* Closes the connection
*
* @throws ConnectionException When the connection isn't open
*/
public final function terminate () {
if (!$this->isInitialized()) {
throw new ConnectionException("Database is closed");
}
$this->instance = null;
}
/**
* @return null|PDO
*/
public function getInstance () {
return $this->instance;
}
}
初始化与mysql服务器的连接(将其视为XAMPP)。
为了在mysql服务器连接中使用数据库(及其功能),我创建了另一个类:
/**
* Represents a database (with it's functions if its correctly set up)
*/
class Database
{
/**
* The mysql server we are connected to
*
* @var MySQLServerConnection $serverConnection The mysql server connection
*/
private static $serverConnection;
/**
* The name of the database we are currently using
*
* @var string $name The database name
*/
private static $name;
/**
* Sets up a database from a initialized MySQL server connection.
*
* @see MySQLServiceConnection
*
* @param MySQLServerConnection $serverConnection
* @param string $name
*
* @return $this|DatabaseStatements
*/
public static final function setup (MySQLServerConnection $serverConnection, $name) {
/*
* Check if the database server has not been initialized yet
*/
if (!$serverConnection->isInitialized()) {
throw new LogicException("Database can't be set up, the connection to the server isn't open yet.");
}
self::$serverConnection = $serverConnection;
self::$name = $name;
if (!empty($name)) {
self::__use($name);
}
/*
* Give access to database functions
*/
return new DatabaseStatements(new self);
}
/**
* Selects the database for usage where our tables are located
*
* @param string $databaseName The database name
*/
public function __use ($databaseName) {
if (!empty($databaseName)) {
self::$serverConnection->getInstance()
->exec("USE $databaseName");
}
}
/**
* @return MySQLServerConnection
*/
public function getServerConnection () {
return self::$serverConnection;
}
/**
* Gets the name of the selected database
*
* @return string The database name
*/
public function getName () {
return self::$name;
}
}
并将其与这段代码一起使用:
$databaseConnection = new MySQLServerConnection("127.0.0.1", "root", "");
try {
$databaseConnection->initialize();
$database = Database::setup($databaseConnection, "phpmyadmin");
} catch (ConnectionException $e) {
}
$database
对象现在可以访问DatabaseStatements
类,其中包含所有函数。
/**
* Class DatabaseStatements
*
* Represents all the database statements
*/
class DatabaseStatements
{
/**
* @var Database $database Which database we are executing our functions on
*/
private $database;
/**
* @param \Database $database
*/
public final function __construct (Database $database) {
$this->database = $database;
}
/**
* Selects data out of the database
*
* @param array $data The data getting selected from the database
*
* @return \SelectStatement
*/
public function select ($data) {
return new SelectStatement($data);
}
......
}
}
我的想法是当你在DatabaseStatements
类中调用一个函数时,你将返回另一个类(在这种情况下为SelectStatement
)。因此,数据库函数在不同的类上进行分割。
class SelectStatement extends Statement
{
/**
* @var array $data The data which is getting selected
*/
private $data = [];
/**
* Select's specific columns from the database
*
* @param array $data The data which is getting selected
*/
public final function __construct (array $data) {
//....
return $this;
}
/**
* @param string $location
*
* @param bool $execute
*
* @return \Statement
*/
public function from ($location, $execute = false) {
// ...
return $this;
}
}
在这个类中是与SelectStatement
相关的其他函数(例如from()
),以及构建和执行查询的能力。
调用from()
函数后,我们可以访问其他一些数据库函数,例如join
或when
。 (这些都在Statement
班。
class Statement
{
public function join (array $tables){
}
public function when ($condition) {
}
}
现在我的问题是,我无法访问$database
类中的SelectStatement
变量,并且将其作为变量传递到{{1}内部似乎不是一个好主意构造函数。
问题
如何以良好的方式访问类中的SelectStatement
变量(代表$database
等函数)。 (我认为传递它作为另一个变量非常糟糕)
将功能划分到不同的类别是否合适?
答案 0 :(得分:0)
<?php
/**
* Class DatabaseStatements
*
* Represents all the database statements
*/
class DatabaseStatements
{
/**
* @var Database $database Which database we are executing our functions on
*/
private $database;
public $selectStatement;
/**
* @param \Database $database
*/
public final function __construct ($database) {
$this->database = $database;
$this->selectStatement = new SelectStatement();
}
/**
* Selects data out of the database
*
* @param array $data The data getting selected from the database
*
* @return \SelectStatement
*/
}
class SelectStatement extends Statement
{
/**
* @var array $data The data which is getting selected
*/
private $data = [];
/**
* Select's specific columns from the database
*
* @param array $data The data which is getting selected
*/
public function select (array $data) {
$this->data['select'] = $data[0];
return $this;
}
/**
* @param string $location
*
* @param bool $execute
*
* @return \Statement
*/
public function from ($location, $execute = false) {
$this->data['from'] = $location;
return $this;
}
}
class Statement
{
public function join (array $tables){
}
public function when ($condition) {
}
}
$DatabaseStatements = new DatabaseStatements('database object');
$DatabaseStatements->selectStatement->select(array('test'))->from('table');
var_dump($DatabaseStatements);
结果:
object(DatabaseStatements)[1]
private 'database' => string 'database object' (length=15)
public 'selectStatement' =>
object(SelectStatement)[2]
private 'data' =>
array (size=2)
'select' => string 'test' (length=4)
'from' => string 'table' (length=5)