我正在编写自己的OOP框架,部分是作为一种学习练习,但知道这个代码库不会消失 - 只会随着我的学习而发展。下面是我的设置看起来像的一些伪代码。在此设置中,我将如何共享数据库连接?用ctrl + f进行“连接”以找到代码中的位置我特别不确定如何构造。
路由文件如下所示:
switch($urlParameters['action']){
case 'lading':
//etc etc
break;
case 'userCP':
//etc etc
break;
case 'dashboard':
default:
$page = new dashboard();
$page->route($urlParameters);
break;
}
页面看起来像
<?php
abstract class page{ // Page is a mixture of controller and view. Most view logic is frontend, so I do all my controller-view logic here
public var $models;
public var $session;
public var $user;
function __construct(){
$this->models = new models();
$this->session = $this->models->session(new MongoID($_COOKIE['session'])); // Plus some code to prevent session hijacking
$this->user = $this->models->users($this->session->userID);
}
function outputMongoData(){} // Wrapper function used by pages to output Mongo datatypes as regular json (Dates to RFC, IDs to string, rounding floats, etc)
function template($file, $data){} // This uses output buffering and extract() to use php its self as the templating language.
}
class dashboard extends page{
public var $dashboardView;
function __construct(){
parent::__construct();
$this->dashboardView = $this->models->dashboardView($this->user->dashboardViewID);
}
function route($urlParams){
$this->session->updatePageViewCountOrSomething();
echo $this->template('dashboard.php', [
'importantData' => $this->dashboardView->someTypeOfDataFromDashboardView,
'viewCount' => $this->session->pageViewCount
]);
}
}
模型看起来像
<?php
class models{
private var $cache = [
'users' => [],
'dashboardViews' => [],
'sessions' => [],
];
// Cache to prevent collisions since we're doing save() vs individual updates, plus saves overhead of querying multiple times (potentially hundreds of times for certain models)
function __construct(){
// Potential connection sharing stuff here
}
private function modelFactory($collection, $modelName, $identifier){
$stringID = (string) $identifier;
if(!isset($this->cache[$collection][$stringID])){
$this->cache[$collection][$stringID] = new $modelName($identifier);
}
return $this->cache[$collection][$stringID];
}
public function session(MongoID $sessionID){
return $this->modelFactory('sessions', 'session', $sessionID);
}
public function user(MongoID $userID){
return $this->modelFactory('users', 'user', $userID);
}
public function dashboardView(MongoID $dashboardViewID){
return $this->modelFactory('dashboardViews', 'dashboardView', $dashboardViewID);
}
}
abstract class model{
public var $db;
public var $collection;
private var $data = [];
function __construct($collectionName){
$this->db = // ??? Not sure how to connect so that I don't have a new connection for every single model..
$this->collection = $this->db->{$collectionName};
}
function __destruct(){
$this->collection->save($this->data);
}
function __get($fieldName){
return $this->data[$fieldName]; // if isset, etc etc
}
}
class session extends model{
// Explanation of schema here
function __construct(MongoID $sessionID){
parent::__construct('sessions');
$this->data = $this->collection->findOne(['_id' => $sessionID]); // or if not found, create..
}
function updatePageViewCountOrSomething(){
$this->data['pageViewCount'] += 1;
$this->data['orSomething'] = ['something' => 'or another'];
}
}
class dashboardView extends model{
// Explanation of schema here
function __construct(MongoID $dashboardViewID){
parent::__construct('dashboardViews');
$this->data = $this->collection->findOne(['_id' => $sessionID]); // or if not found, create..
}
function addColumns(){}
function reorderColumns($newOrder){}
}
答案 0 :(得分:1)
从您的示例中,models
类看起来像是模型实例的工厂。在这种情况下,您可以将它用作连接容器,然后将相应的MongoCollection
实例传递给每个模型类而不是集合名称。
我还要注意,在PHP驱动程序中,构建多个MongoClient
对象并不存在问题。驱动程序在内部使用持久连接,因此构建具有相同主机/端口/用户/密码组合的五个MongoClient
实例仍将仅在后台创建单个网络套接字。您可以使用this slide中的示例和后面的示例自行测试。
您model
实施的一些常见问题:
$data
是基础model
类的私有,但您可以在子类中访问它。它应该受到保护。__destruct()
将对象保存回数据库似乎是一个坏主意,因为它可能发生在脚本的末尾,或者如果对象被垃圾收集,则会在某个时间发生。在应用程序中有一个可预测的点来写入数据似乎更合适。$SESSION
)使用的自定义存储后端(在本例中为MongoDB)。创建框架(即使是思考练习)之前的一个很好的起点是阅读设计模式。 Anthony Ferrara的blog是一个很好的资源和主题的起点。我还建议学习依赖注入和服务容器,因为这与您关于共享公共资源(例如数据库连接)的原始问题非常相关。 Fabien Potencier在这个问题上表现出色blog series。这篇文章已有几年历史,并且引用了Symfony 1.x实现(Symfony2是他使用的当前模型),但早期的帖子很可能是一个有用的介绍。