I'm creating an application that makes use of 3 different databases on different servers. Fetching data happens in my Data mappers, each extending an abstract DataMapper parent class:
abstract class DataMapper {
protected $db;
protected $db2;
protected $db3;
function __construct() {
$this->db = new Database('db1');
$this->db2 = new Database('db2');
$this->db3 = new Database('db3');
}
}
However, this would be a little overkill for pages that only requires one of these 3 connections. What would be the best way to return the correct Database connection for every part of the application? I've heard about Application Registries, but I have no idea how to set up something like that.
I don't like how you're setting up your data mappers. You're creating a new connection for every mapper, even if it uses a provider that already has an established connection. In other words, every data mapper creates a new database object.
Ideally, these database objects should be saved and passed to the data mappers that need them. Auto injecting typically works pretty well. What that means is you don't have to instantiate objects with the new keyword, but by requesting them through your object's constructing paramters.
For example:
class Example1Mapper extends DataMapper {
function __construct( Provider1 $provider1 ) { ... }
}
class Example2Mapper extends DataMapper {
function __construct( Provider1 $provider1, Provider2 $provider2 ) { ... }
}
Above, two mapper classes need different providers. The only thing you need to do is specify this through the object's constructor. Automatic dependency injecting/autowiring does the rest.
I don't know how your architecture is established, but this is what I do: the router and injector work together. The router determines what controller should be called and what action (method) should be called. The injector takes this information and reflects the controller's parameters. It also reflects the paramters' paramaters, and so on... The injector creates all the objects and decides what db providers, domain objects, etc... to pass. Here and here would be good places to begin learning on injectors, but you probably want to do some reading around. There are also a few good lightweight DICs.
Related
I have built a small PHP MVC framework and just want to clarify the best way to get data from one model into another. For example:
I have a Users_model that contains a method called get_users().
I also have Communications_model that needs to get specific or all user data and as such needs to access the get_users() method from the Users_model.
Is it best practice to:
a) Instantiate the Users_model in a controller and pass the data from the get_users() method into the Communications_model?
b) Instantiate the Users_model inside the Communications_model and run get_users() from there, so it can be accessed directly?
c) Another way?
Many thanks for any help.
It depends of your motive behind this.
If you want effect on result, then using well know library, like Doctrine etc. should be your choice.
If you want to learn design patterns, then you should get read about ActiveRecord or DataMapper + Repository patterns. Then implements both and check out.
If you want your code, this way - ORM should represent relations of data, then you should ask what it more important? If you menage communication (bus, train), then user can be there assigned and getting users from communication is OK. If user have communication (like car), then relation is reversed.
All depends, what is you motive behind this. Using library, like Doctrine, could you help you running you application. If you want learn design patterns, then check out both options to get some experience.
What you call "users model" is a repository. And what you call "communication model" looks like a service.
Your communication service should have the user repository passed in constructor as a dependency.
I honestly think, that a huge part of your confusion is that you try to call all of those things "models". Those classes are not part of the same layer. You migth find this answer to be useful.
All are possible ways but what I usually do is, whenever there is any function that I think would be reused a number of times by a number of objects, I declare it as static.
It would save the effort of playing with object declaration and would be easily accessible by ClassName::function();
Again, it's a design choice, usually objects are declared right there in the controller and used as per the need but just to save declaration of objects again and again I follow the approach of declaring function static.
The simple principle here is using the __construct() (constructor) to build the object with the relevant properties from the Database. The User Model will have a static function (therefore accessible through any scope) to create an array of instanced objects by simply passing the model data through a new self() which returns the instance.
The concept is you end up with an array of User_Model instances each being a build of the Database columns to properties. All that's left is to create the Database Model and the functions to retrieve the columns and data.
class Communications_Model {
private $_all_users;
public function getUsers() {
$this->_all_users = Users_Model::loadAllUsers();
}
}
class Users_Model {
private $_example_property;
public function __construct($user_id) {
$data = SomeDatabaseModel::getConnection()->loadUserFromDatabase((int)$user_id);
$this->_example_property = $data['example_column'];
}
public static function loadAllUsers() {
$users = array();
foreach(SomeDataModel::getConnection()->loadAllUsers() as $data) {
$users[] = new self($data['user_id']);
}
return $users;
}
}
Of course, now, you have a $_all_users; property that has an array of instanced User Models containing the data.
A user fills in the form and submits it. Based on the input, an object Organization is hydrated. I want to separate communication with database from the actual object.
I thought of creating an OrganizationMapper that holds the methods for database communication (save, delete...). The organization class would get the OrganizationMapper through the constructor.
With these class definitions, however, I can't instantiate the classes because of their mutual dependence.
How else could I separate the database communication from Organization and put it into OrganizationMapper?
class Organization
{
protected $id;
protected $name;
... other properties ...
public function __construct(OrganizationMapper $mapper)
{
$this->mapper = $mapper;
}
public function getId() {...}
public function setId($id) {...}
... other methods ...
public function saveToDb()
{
$this->mapper->save($this);
}
The OrganizationMapper is
class OrganizationMapper
{
public function __construct(Organization $organization)
{
$this->organization = $organization
}
... other methods
public function save($organization)
{... the code to use the methods of Organization class to save the data to the database...}
}
And that's why circular dependencies are usually considered a bad thing.
Kidding aside, it seems to me that you do not actually need the constructor dependency in the OrganizationMapper class. From the looks of it, you're passing the Organization instance that you want to persist as a parameter into the mapper's save() method anyway and shouldn't need the instance attribute $this->organization in that class at all.
In general, I'd try to keep the OrganizationMapper stateless. Try to avoid storing an Organization instance as an instance attribute (especially if you actually use that same mapper instance for persisting multiple Organizations). Just do as you already did with the save() method and pass the Organization object as a method parameter.
Also, I would not associate the Organization class with the mapper. One could argue that this violates the Single Responsibility Principle as it's not the class' responsibility to persist itself. You could move this logic to the calling code and have the Organization class not know about the mapper at all (which is nice, because you completely eliminate the circular dependency between the two classes):
class Organization
{
protected $id;
protected $name;
// <other properties here>
// <getters and setters here>
}
class OrganizationMapper
{
public function save(Organization $organization)
{
// save $organization to DB, somehow
}
}
$organization = new Organization();
$organization->setName('Foobar International Inc.');
$mapper = new OrganizationMapper();
$mapper->save($organization);
To find a better way of seperating these two concerns, think about the purposes of your two objects:
an Organization is there to give you access to all informations of an organization
your OrganizationMapper is there to save a Organization object to database.
When you think about it like this, then there's a couple of questions, that rise up:
Why does your Organization need a saveToDb() method? It's not it's job to save it?
An instance of OrganizationMapper should be able to save any Organization in the database, so why do you pass it in twice? (once in the constructor, and once in the save($organization) method). In that case - what happens, if you pass a different organization to the constructor than to the save method?
In your current example, how would you load an Organization from Database?
As alternative, I would suggest to remove saveToDb() from Organization entirely, as it's not the job of the org to save itself to database. Additionally, I would remove the current Constructor from OrganizationMapper. In it's current design, there's little reason to pass the Organization to the constructor.
Also, I would rename the OrganizationMapper to OrganizationRepository or OrganizationService. The primary purpose of that class is not to map SQL to Objects but to retrieve/save Organizations from/to DB. (Also, in OOP, classes should only follow the single responsibility pattern, so maybe the part mapping between SQL and Objects should happen in specializied class)
As a side note: generally, it's not a great idea, to give many ways to do exactly the same thing (e.g. saving an organization). This will probably just cause inconsistencies over time (consider that you will be adding some validation logic in the future, but might forget to also add it in the second place).
I hope this helps you :)
Disclaimer: I name your Organization type as OrganizationEntity in this post.
Pretty simply, it's the other way around.
The OrganisationMapper gets an OrganisationEntity object and persists it to wherever you want to, by means you can choose.
For your problem:
move the saveToDb() method from your OrganisationEntity to the OrganisationMapper and pass it an object to be saved.
I don't know why Mapper should do any opperations on DB? Mapper sounds like converting Entity (Organization) into something that can be an input for DB operation ie. Query Object.
You should rename your class into DAO or Repository. It would be better name.
IMHO, the best idea would be to have:
Organization as an object that holds domain logic
OrganizationMapper should convert your domain object into some kind of query object
OrganizationDao should take Organization as an input param and use OrganizationMapper to convert it and do operation on DB.
BTW, why you are not using some kind of an ORM like Doctrine for example? It would make your life easier :)
You can't do that in php. Imagine if it would be posibble. Then instance of Organization would have a property OrganizationMapper, which would have a property Organization. So, property of a property of an instance of the class would be the instance itself! It is only possible in languages with pointers like c++. So, I see only 2 solutions here:
Put the classes together
Have a single link (maybe have 1 class that calls another while second doesn't call first.)
I've been researching and reading a lot about working with separate layers in PHP to create maintainable and readable code.
However, I see a lot of code where the entity and the database access is placed in one class.
For example:
class User{
public $id;
public $username;
public $database;
function add(){
$database->query ....
}
}
I find this rather strange because here you are mixing the User class with database elements which makes it more difficult to maintain.
I like working like this:
a separate database class
a user class
a userData class
This works like this:
$database = new Database();
$database->openConnection();
$dataUser = new DataUser($db);
$user = new User(1,"myname");
$dataUser->saveUser($user);
So I'm wondering, am I working the right way or is the first way a better way to create code?
I find may way very easy to maintain because you have a separate entity and a separate database class to handle the database actions.
What i do :
My models are not Entities linked to the database(when i'm not using doctrine) , so no "active record" methods. An object doesnt know how to fetch its dependencies ( for instance , a user may have n comments, my model doesnt know how to get comments ).
class User{
private $name;
private $password;
// getter and setters
}
i have services that hold some business logic that can fetch models from providers, a service can have many providers.
class UserService{
function __construct(IUserProvider $userProvider){
$this->userProvider = $userProvider
}
function getUsers(){
// return an array of user objects
return $this->userProvider->getUsers();
}
}
finally i have a data provider that knows how to request datas from the database , a text file , a json file , a webservice :
class UserProvider implements IUserProvider{
function __construct(Connection $connection){
$this->connection = $connection;
}
function getUsers(){
return $this->toUsers($this->connection->fetchAssoc("Select * from users"));
}
function toUsers(array $datas){
// convert user records to an array of User
(...)
return $users;
}
}
then the interface
interface IUserProvider{
/**#return array an array of User */
function getUsers();
}
if i need to get a user comments , then my comment service knows how fetch comments from a user id. So to get a user and its comments , i need 2 requests to the database. one from the UserProvider , the other from the CommentProvider.
so i have 3 layers :
my application layer ( display users , respond to requests whatever ... )
my service layer ( which has to work with a command line interface and is not aware of my web application , except for password encoding which is usually binded to the framework i use , and ACL stuffs maybe ...)
my data access layer which knows nothing about the other layers ,
the only way my layers communicate is through Models i pass from layer to layer.
And all my classes are built with a dependency injection container, so the wiring is not a problem.
Here is an exemple of an app i made,it's open source : https://github.com/Mparaiso/silex-bookmarkly
Any thoughts welcome.
easy to maintain because you have a separate entity and a separate
database class
It appears you're saying that you wish to move away from an Active Record approach to a Data Mapper/Entity/Repository approach. That's a good direction to move in because it employs better separation of concerns. You can build this yourself but you might want to take a look at solutions like Doctrine where it allows you to do something along the lines of:
$product = new Product();
$product->setName($newProductName);
$entityManager->persist($product);
The $product entity is just a POPO (Plain Old PHP Object) that contains the record data and is unaware of how it's persisted and, when persistence is needed, is passed into the entity manager to take care of the storing.
Personally, I think abstracting UserData from User is likely to be overkill. As, in this case, UserData is likely to be very similar to ProductData for example - they're still going to contain an add($data), find($id) etc.
In your case, User is a model in the MVC approach, and is totally acceptable to contain Database store/retrieve logic. You will however likely find that you are, again recreating the same DB methods in the User class that you have in other Models. This is where you may start to look at an ORM implementation. Whereby the common DB access methods are defined in an abstract class that all your models then extend and override as necessary.
I'm building a web application that needs to be able to write data to either a mysql db or an xml file, depending on the online status of the application.
In my model, I have a super class (Dao is data access object)...
abstract class Dao {
static function getInstance($online_status) {
if $online_status = 'online' {
return new DaoMySQL;
} else {
return new DaoXML;
}
}
abstract function dao_select();
abstract function dao_insert();
abstract function dao_update();
abstract function dao_delete();
}
Now, here is the part I'm confused about. I have a domain model/entity class that selects the appropriate Dao using:
$this->dao = Dao::getInstance($online_status);
So, now I have the correct data access object selected. But, the problem is I still two implementations of dao_select() and the other functions. Now, the main implementations are in the respective classes DaoMySQL and DaoXML, but dao_select() in each of those classes require different things. i.e. the DaoMySQL version needs two parameters, $table and $where_statement. DaoXML (which I haven't implemented) will need the element name, and maybe another argument, I don't know.
So, in my domain model class, after calling
$this->dao = Dao::getInstance($online_status);
is this where I need to include two separate local implementations (pertaining to the domain model/entity class only) of dao_select(), or this wrong? It just seems like I'm taking the elegance out of the process by doing something like this:
class EntityModel {
$this->dao = Dao::getInstance($online_status);
if($this->dao->type = 'mysql') {
$result = $this->dao->dao_select($table, $where);
} else {
$result = $this->dao->dao_select($xml_params);
}
}
I feel like I'm taking the simplicity out of the system... Does this approach make sense, or is there a better one?
You are doing it wrong.
Few notes to begin with:
in OOP the extends statement signifies is a relationship. Which means that, while class Duck extends Bird is all fine, writing class User extends Table is NOT.
in MVC the Model is not a class or an instance of a class. Instead it is a layer of application, mostly made of two types of elements:
domain objects: containing domain business rules and logic
data access structures: usually datamapper dealing with storage and retrieval of information
I would argue, that the third significant part of Model layer are services. But there are options on whether it is part-of or above Model.
Currently what you are trying to do is forcing a ActiveRecord (which is fine for small things, but as project grows, it becomes a burden on architecture .. which is what you are face with now) patterns to work with dynamic data sources. And to do so you are resorting to procedural calls.
Anyway, the point is that you should inject your DAO instance into your Domain Objects (what you calls "models"). And you should leave the creating of your DAO to a separate factory instance, which would be responsible for initializing them and providing them with data source (instance of PDO or file path). This way you can, not only separate the responsibilities, but also swap the storage destination "on fly".
To learn more you should investigate what is dependency injection. Here are few video that might help:
Don't Look For Things!
Global State and Singletons
I would like to know where is the best place to set my db object with my model.
Should I hard coded it since my model should be designed for one project, so i set it inside my constructor or wherever i do initialization ?
or
Should I pass my db object to my constructor when instancing my object ?
What is the best way, i mean from experimented users, and efficient that'll give me more confort to use ?
Couple of things:
Most PHP projects that utilize a database connection represent that database using a Singleton pattern, if you aren't sure what this is, read up on it.
Typically I define my database connections in a configuration file which can easily be changed between environments (development, stage, production).
I'll then instantiate my database connection in a bootstrap file using the aforementioned Singleton pattern and configuration file.
My models will typically completely abstract the database/table data store, for each model I'll do something like this:
bootstrap.php
$config = load_config_data(ENVIRONMENT);
Db::setDefaultAdapter($config['database']);
Model/Table/User.php
class Table_User extends Db_Table
{
// Table name
protected $_name = 'user';
/* Do a bunch of database specific stuff */
}
Model/User.php
class User extends Model
{
public function updateUsername($userid, $username)
{
// Uses default adapter, Singleton pattern!
$table = Db::loadTable('user');
$table->update(
array('username'=>$username),
Db::quoteInto('userid = ?', $userid)
);
}
}
This is pretty much an introduction to the Model in the Zend Framework MVC, I would check it out for some ideas on how to organize your code (or save yourself some trouble and actually use the framework.)
For testability, you should pass it into the constructor rather than hard coding it. This helps you to write unit test because you can mock your DB object.
I would not hard code it, even if the code is never used for another project simply moving from a test database to a live database may require locating and changing the code in the model class. That would be far better placed in some kind of configuration file.
Personally, I would have the db object defined in whatever you use as a bootstrap - and then have the model(s) use that single object.