dongliu5475 2014-12-12 15:49
浏览 58

将对象从类传递给类

I'm building a Query Builder (for practice) and for that i needed a database connection, so i created this class:

/**
 * 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;
    }
}

This initializes a connection to a mysql server (See it as XAMPP).

To make use of a database (with its functions) in the mysql server connection, i created another class:

/**
 * 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;
    }
}

And used it with this piece of code:

$databaseConnection = new MySQLServerConnection("127.0.0.1", "root", "");

try {
    $databaseConnection->initialize();
    $database = Database::setup($databaseConnection, "phpmyadmin");

} catch (ConnectionException $e) {

}

The $database object gives now access to the DatabaseStatements class, where all the functions are.

/**
 * 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);
    }

    ......

    }
}

My idea was when you call a function in the DatabaseStatements class, you get returned to another class (SelectStatement in this case). So the database functions are splitted over different classes.

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;
    }
}

In this class are the other functions related to the SelectStatement (such as from()), and the ability to build and execute the query.

When the from() function has been called, we have access to some other database functions such as join or when. (These are in the Statement class.

class Statement
{

    public function join (array $tables){

    }

    public function when ($condition) {

    }
}

Now my problem is, i cant access the $database variable in the SelectStatement class, and it didn't seem like a good idea to pass that in as a variable inside the SelectStatement constructor.

Questions

  • How do i get access to the $database variable inside the classes (which represent the functions such as Select) on a good way. (I thought passing it in as another variable was pretty bad)

  • Is it good to split functionality over different classes?

  • 写回答

1条回答 默认 最新

  • duancheng1955 2014-12-12 16:27
    关注
    <?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);
    

    Result :

    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)
    
    评论

报告相同问题?

悬赏问题

  • ¥17 pro*C预编译“闪回查询”报错SCN不能识别
  • ¥15 微信会员卡接入微信支付商户号收款
  • ¥15 如何获取烟草零售终端数据
  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向