Using Doctrine with Slim

This cookbook entry describes how to integrate from scratch the widely used Doctrine ORM into a Slim application.

Adding Doctrine to your application

The first step is importing the library into the vendor directory of your project using composer.

  1. composer require doctrine/orm:^2
Figure 1: Require doctrine in your application.

Provide database credentials

Next, add the Doctrine settings alongside your Slim configuration.

  1. <?php
  2. // settings.php
  3. define('APP_ROOT', __DIR__);
  4. return [
  5. 'settings' => [
  6. 'displayErrorDetails' => true,
  7. 'determineRouteBeforeAppMiddleware' => false,
  8. 'doctrine' => [
  9. // if true, metadata caching is forcefully disabled
  10. 'dev_mode' => true,
  11. // path where the compiled metadata info will be cached
  12. // make sure the path exists and it is writable
  13. 'cache_dir' => APP_ROOT . '/var/doctrine',
  14. // you should add any other path containing annotated entity classes
  15. 'metadata_dirs' => [APP_ROOT . '/src/Domain'],
  16. 'connection' => [
  17. 'driver' => 'pdo_mysql',
  18. 'host' => 'localhost',
  19. 'port' => 3306,
  20. 'dbname' => 'mydb',
  21. 'user' => 'user',
  22. 'password' => 'secret',
  23. 'charset' => 'utf-8'
  24. ]
  25. ]
  26. ]
  27. ];
Figure 2: Slim settings array.

Define the EntityManager service

Now we define the EntityManager service, which is the primary way to interact with Doctrine.Here we show how to configure the metadata reader to work with PHP annotations, which is at thesame time the most used mode and the most tricky to set up. Alternatively, XML or YAML can alsobe used to describe the database schema.

  1. <?php
  2. // bootstrap.php
  3. use Doctrine\Common\Annotations\AnnotationReader;
  4. use Doctrine\Common\Cache\FilesystemCache;
  5. use Doctrine\ORM\EntityManager;
  6. use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
  7. use Doctrine\ORM\Tools\Setup;
  8. use Slim\Container;
  9. require_once __DIR__ . '/vendor/autoload.php';
  10. $container = new Container(require __DIR__ . '/settings.php');
  11. $container[EntityManager::class] = function (Container $container): EntityManager {
  12. $config = Setup::createAnnotationMetadataConfiguration(
  13. $container['settings']['doctrine']['metadata_dirs'],
  14. $container['settings']['doctrine']['dev_mode']
  15. );
  16. $config->setMetadataDriverImpl(
  17. new AnnotationDriver(
  18. new AnnotationReader,
  19. $container['settings']['doctrine']['metadata_dirs']
  20. )
  21. );
  22. $config->setMetadataCacheImpl(
  23. new FilesystemCache(
  24. $container['settings']['doctrine']['cache_dir']
  25. )
  26. );
  27. return EntityManager::create(
  28. $container['settings']['doctrine']['connection'],
  29. $config
  30. );
  31. };
  32. return $container;
Figure 3: Defining the EntityManager service.

Create the Doctrine console

To run database migrations, validate class annotations and so on you will use the doctrine CLI application that isalready present at vendor/bin. But in order to work, this script needs a cli-config.phpfile at the root of the project telling it how to find the EntityManager we just set up:

  1. <?php
  2. // cli-config.php
  3. use Doctrine\ORM\EntityManager;
  4. use Doctrine\ORM\Tools\Console\ConsoleRunner;
  5. use Slim\Container;
  6. /** @var Container $container */
  7. $container = require_once __DIR__ . '/bootstrap.php';
  8. ConsoleRunner::run(
  9. ConsoleRunner::createHelperSet($container[EntityManager::class])
  10. );
Figure 4: Enabling Doctrine's console app.

Take a moment to verify that the console app works. When properly configured, its output will look more or less like this:

  1. $ php vendor/bin/doctrine
  2. Doctrine Command Line Interface 2.5.12
  3. Usage:
  4. command [options] [arguments]
  5. Options:
  6. -h, --help Display this help message
  7. -q, --quiet Do not output any message
  8. -V, --version Display this application version
  9. --ansi Force ANSI output
  10. --no-ansi Disable ANSI output
  11. -n, --no-interaction Do not ask any interactive question
  12. -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
  13. Available commands:
  14. help Displays help for a command
  15. list Lists commands
  16. dbal
  17. dbal:import Import SQL file(s) directly to Database.
  18. dbal:run-sql Executes arbitrary SQL directly from the command line.
  19. orm
  20. orm:clear-cache:metadata Clear all metadata cache of the various cache drivers.
  21. orm:clear-cache:query Clear all query cache of the various cache drivers.
  22. orm:clear-cache:result Clear all result cache of the various cache drivers.
  23. orm:convert-d1-schema [orm:convert:d1-schema] Converts Doctrine 1.X schema into a Doctrine 2.X schema.
  24. orm:convert-mapping [orm:convert:mapping] Convert mapping information between supported formats.
  25. orm:ensure-production-settings Verify that Doctrine is properly configured for a production environment.
  26. orm:generate-entities [orm:generate:entities] Generate entity classes and method stubs from your mapping information.
  27. orm:generate-proxies [orm:generate:proxies] Generates proxy classes for entity classes.
  28. orm:generate-repositories [orm:generate:repositories] Generate repository classes from your mapping information.
  29. orm:info Show basic information about all mapped entities
  30. orm:mapping:describe Display information about mapped objects
  31. orm:run-dql Executes arbitrary DQL directly from the command line.
  32. orm:schema-tool:create Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output.
  33. orm:schema-tool:drop Drop the complete database schema of EntityManager Storage Connection or generate the corresponding SQL output.
  34. orm:schema-tool:update Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata.
  35. orm:validate-schema Validate the mapping files.
Figure 5: Test-driving Docrine's console application.

If it works, you can now create your database and load the schema by running php vendor/bin/doctrine orm:schema-tool:update

Using the EntityManager in our own code

Congratulations! Now you can already manage your database from the command line, and use the EntityManager wherever you need it.

  1. $container[UserRepository::class] = function ($container) {
  2. return new UserRepository($container[EntityManager::class]);
  3. };
  4. // src/UserRepository.php
  5. class UserRepository
  6. {
  7. /**
  8. * @var EntityManager
  9. */
  10. private $em;
  11. public function __construct(EntityManager $em)
  12. {
  13. $this->em = $em;
  14. }
  15. public function signUp(string $email, string $password): User
  16. {
  17. $user = new User($email, $password);
  18. $this->em->persist($user);
  19. $this->em->flush();
  20. return $user;
  21. }
  22. }
Figure 6: Using the EntityManager service.

Other resources