【问题标题】:Initializing multiple classes an the bootstrap process在引导过程中初始化多个类
【发布时间】:2015-10-28 22:43:24
【问题描述】:

我正在尝试制作一个仅用于学习目的的 MVC 框架。

在这个阶段,我创建了一个 Application 类,我正在考虑进行引导,例如基于配置设置错误报告以及设置 $db 实例。

我有一个通用的文件夹结构,例如模型、控制器、视图、库和核心。

在我的核心中,我将有数据库、会话、验证等类。

我不明白如何将所有这些实例传递给持有受保护的 $instance 属性的相应类,以便继承模型和控制器可以访问它们。

例如在我的初始化过程中我已经完成了

<?php
use Core\Config;

class Application
{
    public function __construct()
    {
        // Load runtime configuration
        require_once 'config/config.php';
        $this->errorHandler();

    }

    private function setDbConnection()
    {
        switch (Config::$config['database']['dbdriver'])
        {
            case 'MySQLi':
                $db = new mysqli(Config::$config['database']['dbhost'], Config::$config['database']['dbuser'], Config::$config['database']['dbpass'], Config::$config['database']['dbname']);
                break;

            case 'PDO':
                $dsn = 'mysql:host='.Config::$config['database']['dbhost'].';dbname='.Config::$config['database']['dbname'];
                $db =  new PDO($dsn, Config::$config['database']['dbuser'], Config::$config['database']['dbpass']);
                break;

            default:

                break;
        }
    }


}

$application = new Application;

如何将这个 dbConnection 传递给我的 core/Database.php,以便我的模型将扩展 Database.php 并让 $db 进行查询等。

这也是好主意还是我在性能方面做错了。

【问题讨论】:

  • 你应该尝试 Laravel 使用的 IoC 容器逻辑,你可以有一个静态对象,它将键绑定到对象实例或服务提供者。
  • 对于初学者来说太难了

标签: php oop model-view-controller


【解决方案1】:

希望我不会太晚,但您可以尝试使用单例上下文对象,这将允许全局访问您的对象并避免使用静态类。

您需要做的就是在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 );
?>

我没有测试代码,但应该足以给你这个想法

干杯

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-04
    • 2014-10-14
    • 2015-06-10
    • 2017-06-28
    • 1970-01-01
    • 2015-04-28
    • 2021-07-30
    • 1970-01-01
    相关资源
    最近更新 更多