1

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.

Beeelze
  • 503
  • 1
  • 9
  • 25
  • I get it from [here](http://stackoverflow.com/questions/659970/why-is-it-not-advisable-to-have-the-database-and-web-server-on-the-same-machine) that the app server and the DB server should typically be different, but why exactly are u using different Servers for different DB which are used in the same app(correct me if I'm wrong) – Parthapratim Neog Jun 17 '16 at 12:05
  • One of these databases is a PowerDNS MySQL database which is on a different server than my web server. – Beeelze Jun 17 '16 at 12:11
  • is `new Database('...')` how you establish connection to all 3? or is that just pseudo? – jeremy Jun 20 '16 at 05:23
  • @Jeremy What do you mean exactly? When selecting a database I establish a connection with `new Database('database_name')`. I need to find a way so that I don't have to type `new Database()` all the time. I could write 3 abstract DataMappers for each database and extend my child data mappers. Would that be a 'OK' way to do it? – Beeelze Jun 20 '16 at 07:52
  • I'm not sure. I use autowiring, so I guess what I would do is have controllers request the connection(s) they need and let the injector do the rest by reflecting the controllers parameters. I can elaborate in an answer if you think it would answer your question – jeremy Jun 20 '16 at 23:21
  • On the other hand, I think you're going about constructing data mappers wrong. You're creating new database connections for every construction of a data mapper. This is problematic. The old way to fix this was using a factory to create datamappers, which would pass a connection to the mapper. If no connection existed, it would create one and save it for the next datamapper that needed a connection. The new way is autowiring: letting the mapper say it needs a connection and having the injector create/pass it. – jeremy Jun 20 '16 at 23:25

1 Answers1

0

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.

Community
  • 1
  • 1
jeremy
  • 9,965
  • 4
  • 39
  • 59
  • Thanks, this is something I can continue developing on. I've got a router and I'm using a dependency injector, both work fine independently. Now I need to find a way to bring these two components together. – Beeelze Jun 24 '16 at 08:01
  • @Beeelze I don't think you necessarily need to bring them together. As long as your dependency injector can reflect the parameters a mapper needs and determine what db providers to pass through – jeremy Jun 24 '16 at 12:05
  • Yeah, they can, that's no problem. And where would I put the credentials for each providers for creating a connection? In the Provider classes themselves? Right now I'm using a config.php file which stores all credentials for all databases. – Beeelze Jun 24 '16 at 12:54