This is my problem, I have a tiny PHP MVC framework i built. Now when Im in Controller, i should be able to load a Model. I have Models named like database tables like Users.php, Pages.php etc.
All Controllers extend BaseController, and all Models extend BaseModel, this way I can have some methods available to all Controllers. Like from any Controller I can use loadModel method like this:
$usersModel = $this->loadModel("Users");
Now $usersModel will be object that represents users database table, and from there I should open database connection, and fetch, update, delete stuff from users table.
To get database connection from my Models, baseModel has method loadDatabase() and I use it like this:
$database = $this->loadDatabase();
This would return class that is thin layer around PDO so from there I can use something like this:
$data = $database->fetchAssoc("SELECT * FROM users WHERE name = ?", array("someone"));
This is how I would return some $data from Model to the Controller.
So basicly, Controller can load a model, and then call methods on that model that would return some data or update or delete etc.
Now, Controller can load more then one model. And each model should load database, and this is where it gets complicated. I need only one connection to the database.
This is how loadDatabase method looks:
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);
}
So before I load a Database object, i must load configuration for database connection, as Database objects __constructor expects it. Then I instanciate new database object and return it.
Now Im stuck and I dont know is this the right way to loadDatabase from model? How should I set this up, how should I load database from inside the model so there is always only one instance of database object. Beacuse if I do something like this from Controller:
$users = $this->loadModel("Users");
$pages = $this->loadModel("Pages");
$users->doSomethingThatNeedsDatabase();
$users->doSomethingThatNeedsDatabase();
$pages->doSomethingThatNeedsDatabase();
I would create 3 database objects :(
So my question is, how should I load Database from inside the Models, and how should that method look in BaseModel? What if I would like to use 2 databases, I will have some big problems with this setup. How can I achive this without using singleton pattern?
At the moment, I also have something like this:
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, $username, $password, $options);
$reg->setObject('database', $db);
}
return $reg->getObject('database');
}
This is Registry pattern, where I could hold shared objects. So when Model asks for DB connection I could check if DB Class is in Registry, and return it, if not I would instaciate and then return... The most confusing thing is that I need to load configuration array...
So what is the best way, to load Database from Models?
Thanks for reading, this was a very long question, but this is bothering me so much, i hope someone could help me with this one... Thanks!