Search code examples
phpsymfonydatabase-connectionmultiple-databases

symfony2 - using multiple connections in a repository or class


I have multiple connections and I have a repository class. I would like the repository class to have access to the multiple connections. Its for a report that requires fetching data from multiple database hosts.

config.yml

doctrine:
    dbal:
        default_connection:  default
        connections:
          default:
              driver:   "%db_default_driver%"
              host:     "%db_default_host%"
              etc..
          bookings:
              driver:   "%db_readonly_bookings_driver%"
              host:     "%db_readonly_bookings_host%"
              etc ...
          sessions:
              etc..

SalesJournalRepistory.php

namespace Portal\SalesJournalBundle\Repository;

use Doctrine\ORM\EntityRepository;

class SalesJournalRepository extends EntityRepository 
{

  public $connDefault   = null;
  public $connBookings  = null;
  public $connSessions  = null;


  function __construct()
  {
    // this is where I get the error
    $this->connDefault  = $this->getManager('default')->getConnection();
    $this->connBookings = $this->getManager('bookings')->getConnection();
    $this->connSessions = $this->getManager('sessions')->getConnection();
  }

  function testQuery(){
     $sql = "SELECT * FROM testTableBookings LIMIT 10";
     $stmt = $this->connBookings->prepare($sql);
     $results = $stmt->fetchAll();

     print_r($results);
  }

  function testQuery2(){
     $sql = "SELECT * FROM testTableSessions LIMIT 10";
     $stmt = $this->connSessions->prepare($sql);
     $results = $stmt->fetchAll();

     print_r($results);
  }


}

I can make it work from the a controller

$connDefault  = $this->getDoctrine()->getManager('default')->getConnection();
$connBookings = $this->getDoctrine()->getManager('bookings')->getConnection();

however im looking to be able to run it from the repository. Im getting the following error

PHP Fatal error:  Call to a member function getConnection() on a non-object

I thought this may give some clue? enjecting entities however I am a little confused and not sure if it is?


Solution

  • An EntityRepository should only be concerned with its owning entity (and manager)- so mixing your Entity Repositories with your Entity Managers really isn't the way to go. I suggest you create yourself a service and inject Doctrine - then you can query whatever you want. For example :

    the config

    [config.yml / services.yml]
    services:
       sales_journal:
          class: Acme\DemoBundle\Service\SalesJournal
           arguments: ['@doctrine']
    

    the service

    [Acme\DemoBundle\Service\SalesJournal.php]
    
    namespace Acme\DemoBundle\Service;
    
    public class SalesJournal {
    
        private $connDefault;
        private $connBookings;
        private $connSessions;
    
    
        function __construct($doctrine)
        {
            $this->connDefault = $doctrine->getManager('default')->getConnection();
            $this->connBookings = $doctrine->getManager('bookings')->getConnection();
            $this->connSessions = $doctrine->getManager('sessions')->getConnection();
        }
    
        function testQuery()
        {
            $sql = "SELECT * FROM testTableBookings LIMIT 10";
            $stmt = $this->connBookings->prepare($sql);
            $results = $stmt->fetchAll();
    
            print_r($results);
        }
    
        function testQuery2()
        {
            $sql = "SELECT * FROM testTableSessions LIMIT 10";
            $stmt = $this->connSessions->prepare($sql);
            $results = $stmt->fetchAll();
    
            print_r($results);
        }
    }
    

    then from your controller or where ever you want to use the service you can do :

    // get the service
    $sales_journal = $this->get('sales_journal');
    // call relevent function
    $sales_journal->testQuery();