I'm writing my own OOP framework, partially as a learning exercise, but knowing this codebase isn't going to disappear - only evolve as I learn. Below is some psuedocode of what my setup looks like. In this setup, how would I share DB connections? Do a ctrl+f for "connection" to find the places in the code I'm specifically unsure of how to structure.
A routing file would look like this:
switch($urlParameters['action']){
case 'lading':
//etc etc
break;
case 'userCP':
//etc etc
break;
case 'dashboard':
default:
$page = new dashboard();
$page->route($urlParameters);
break;
}
A page would look like
<?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
]);
}
}
And the models look like
<?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){}
}