Search code examples
phpmongodbsymfonydependency-injectiondoctrine-odm

How to share the \Mongo instance between Doctrine ODM and MongoDbSessionHandler?


I'm trying to use MongoDB to store my sessions, and I need to get a reference to the \Mongo instance.

But apparently it's not declared as a service. Instead, doctrine creates it from within the wrapper.

So what can I do about it? I tried this:

services:
    mongo.connection:
        class: MongoDoctrine\MongoDB\Connection
        factory_service: doctrine.odm.mongodb.document_manager
        factory_method: getConnection
    mongo:
        class: Mongo
        factory_service: mongo.connection
        factory_method: getMongo

But sometimes it returns null, and it also conflicts with my logger preprocessor that adds the request_id to the logs, which I think has something to do with the session.

Any ideas?


Solution

  • Looking at the source for Doctrine\MongoDB\Connection, the getMongo() method simply returns the $mongo class property, which may or may not be initialized. If possible, you can call initialize() manually before you inject the connection. Given that you're already defining a service for the Connection wrapper, you should be able to do this:

    services:
        mongo.connection:
            class: Doctrine\MongoDB\Connection
            factory_service: doctrine.odm.mongodb.document_manager
            factory_method: getConnection
            calls:
                - [initialize, []]
        mongo:
            class: Mongo
            factory_service: mongo.connection
            factory_method: getMongo
    

    That would invoke the initialize() method between the container constructing the mongo.connection service from its factory method and it being returned.

    Some additional points to note:

    1. If mongo.connection is only going to be used once (to injected into mongo), you may prefer using anonymous service definitions in lieu of defining another service.
    2. The ODM bundle already defines each connection as doctrine_mongodb.odm.%s_connection, using its name from the configuration in place of %s; however, that's not helpful if you need to add a method invocation to the service definition.
    3. The latest version of the ODM bundle (for Symfony 2.1+) changed its service prefix from doctrine.odm.mongodb to doctrine_mongodb.odm, although a BC alias exists for the default document manager. It'd be wise to switch over to the new prefix, though.