PHP – 从Model加载Database对象的最佳方法,但只有一个实例?

前端之家收集整理的这篇文章主要介绍了PHP – 从Model加载Database对象的最佳方法,但只有一个实例?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这是我的问题,我有一个很小的 PHP MVC框架我建立.
现在,当我在控制器中,我应该能够加载模型.
我的模型名称像Users.PHP,Pages.PHP数据库表.

所有控制器都扩展了BaseController,并且所有模型都扩展了BaseModel,这样我可以为所有控制器提供一些方法.像任何控制器一样,我可以像这样使用loadModel方法

$usersModel = $this->loadModel("Users");

现在$usersModel将是表示用户数据库表的对象,从那里我应该打开数据库连接,并从users表中获取,更新,删除东西.

要从我的模型获取数据库连接,baseModel有方法loadDatabase(),我使用它像这样:

$database = $this->loadDatabase();

这将返回PDO周围的薄层,所以从那里我可以使用这样的东西:

$data = $database->fetchAssoc("SELECT * FROM users WHERE name = ?",array("someone"));

这就是我将一些$data从Model返回给Controller的方法.

所以基本上,Controller可以加载模型,然后在该模型上调用返回某些数据或更新或删除等的方法.

现在,Controller可以加载多个模型.每个模型都应该加载数据库,这就是它变得复杂的地方.我只需要一个数据库连接.

这是loadDatabase方法的外观:

public function loadDatabase()
    {
        // Get database configuration  
        require_once("Application/Config/Database.PHP");

        // Build configuration the way Database Object expects it
        $dns      = "{$db_config['db_driver']}:host={$db_config['db_host']};dbname={$db_config['db_name']}";
        $username = $db_config['db_user'];
        $password = $db_config['db_pass'];
        $options  = $db_config['db_options'];

        // Return new Database object
        return new \Core\Database\Database($dns,$username,$password,$options);

    }

所以在加载Database对象之前,我必须加载数据库连接的配置,因为Database对象__constructor需要它.然后我实例化新的数据库对象并将其返回.

现在我卡住了,我不知道这是从模型加载数据库的正确方法吗?
我应该如何设置它,如何从模型内部加载数据库,因此始终只有一个数据库对象实例.如果我从Controller做了类似这样的事情,请注意:

$users = $this->loadModel("Users");
$pages = $this->loadModel("Pages");

$users->doSomethingThatNeedsDatabase();
$users->doSomethingThatNeedsDatabase();
$pages->doSomethingThatNeedsDatabase();

我会创建3个数据库对象:(

所以我的问题是,如何从模型中加载数据库,以及该方法应该如何在BaseModel中查看?
如果我想使用2个数据库,我将遇到一些大问题.
如何在不使用单例模式的情况下实现此目的?

目前,我也有这样的事情:

public function getDatabase()
{

    $reg = \Core\Registry\Registry::getInstance();
    $db = $reg->getObject("database");
    if(!isset($db))
    {
        require_once("Application/Config/Database.PHP");

        $dns      = "{$db_config['db_driver']}:host={$db_config['db_host']};dbname={$db_config['db_name']}";
        $username = $db_config['db_user'];
        $password = $db_config['db_pass'];
        $options  = $db_config['db_options'];                

        $db = new \Core\Database\Database($dns,$options); 

        $reg->setObject('database',$db);
    }
    return $reg->getObject('database');

}

这是注册表模式,我可以在其中保存共享对象.因此,当Model请求DB连接时,我可以检查DB Class是否在Registry中,并返回它,如果不是我会instaciate然后返回…最令人困惑的是我需要加载配置数组…

那么从模型加载数据库的最佳方法是什么?

感谢您的阅读,这是一个非常长的问题,但这让我非常困扰,我希望有人可以帮助我这个…谢谢!

你正在以错误的方式解决这个问题.

而不是每次手动创建一个新的“模型”,然后配置它,你应该创建一个为你做的结构(非常简化的版本):

class ModelFactory
{
    protected $connection = null;
    // --- snip --

    public function __construct( $connection )
    {
        $this->connection = $connection;
    }
    // --- snip --

    public function buildMapper( $name )
    {
        $instance = new {$name}( $this->connection );
        return $instance;
    }
    // --- snip --

}

您将在index.PHP或bootstrap.PHP中使用的此类,或您用作应用程序入口点的任何其他文件

// at the bootstrap level
$modelFactory = new ModelFactory( new PDO(...) );

// i am assuming that you could get $controllerName 
// and $action from routing mechanism
$controller = new {$controllerName}( $modelFactory );
$controller->{$action}();

您遇到的主要问题实际上是误解了什么是模型.在适当的MVC中,Model是一个层,而不是特定的类.模型层由多个类/实例组成,具有两个主要职责:

>域业务逻辑
>数据访问和存储

第一组中的实例通常称为Domain ObjectsBusiness Objects(有点像geeks and nerds的情况).它们处理验证,计算,不同的条件,但不知道信息的存储方式和位置.它不会改变发票的方式,无论数据来自sql,远程REST API还是MS Word文档的屏幕截图.

其他组主要由Data Mappers组成.它们存储和检索域对象的信息.这通常是您的sql所在.但是映射器并不总是直接映射到数据库模式.在经典的多对多结构中,您可能有1或2或3个映射器为存储提供服务.映射器通常每个域对象一个..但即使这不是强制性的.

在控制器中它看起来都像这样.

public function actionFooBar()
{
    $mapper = $this->modelFactory->buildMapper( 'Book' );
    $book = $this->modelFactory->buildObject( 'Book' );
    $patron = $this->modelFactory->buildObject( 'Patron' );

    $book->setTitle('Neuromancer');
    $mapper->fetch( $book );

    $patron->setId( $_GET['uid']);

    if ( $book->isAvailable() )
    {
        $book->lendTo( $user );
    }

    $mapper->store( $book );

}

也许这会给你一些指示它的方向.

一些额外的视频材料:

> Advanced OO Patterns(slides)
> Global State and Singletons
> Don’t Look For Things!

猜你在找的PHP相关文章