Передача объекта из класса в класс

0

Я создаю 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 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 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, и было бы неплохо передать это как переменную внутри конструктора SelectStatement.

Вопросов

  • Как получить доступ к переменной $database внутри классов (которые представляют такие функции, как Select), на хорошем пути. (Я думал, что передать его в качестве другой переменной было довольно плохо)

  • Хорошо ли разделить функциональность на разные классы?

  • 0
    Почему вы return new SelectStatement($data); а не $this->selectStatement= SelectStatement($data); ? если вы делаете это в SelectStatement, вы можете использовать $ this-> database
  • 0
    @BenjaminPoignant Не могли бы вы привести пример кода, который вы имеете в виду? Я не понимаю, в каком классе это делается?
Показать ещё 4 комментария
Теги:
dependency-injection
oop

1 ответ

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 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)
  • 0
    Это на самом деле не имеет смысла, я даже не использую экземпляр DatabaseStatements внутри моего использования. Я вызываю метод установки из класса базы данных, который возвращает меня в класс databasestatements

Ещё вопросы

Сообщество Overcoder
Наверх
Меню