# Doctrine ORM documentation V3 and V4

**URL:** <https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851>\
**Category:** Questions\
**Created:** [March 25, 2024, 4:03pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851 "2024-03-25T16:03:04Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [March 25, 2024, 4:03pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/1 "2024-03-25T16:03:04Z")

</div>

Good afternoon,

It’ my first message. i greet everybody!  
Firstly, I want to inform you that English is not my first language, and I apologize for my imperfect English. I tried this week-end to configure Slim with doctrine. I had some problems:

> <https://stackoverflow.com/questions/78218852/microiframework-slim-orm-doctrine-some-classes-are-missing-in-the-vendor-fol>

Today, i compare the V3 and V4 versions of the documentation. Are there the same documentation? Is it the V3 version?  
thank’s for your help.

---

<div class="post-metadata">

**Author:** ![akrabat](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.slimframework.com/akrabat/32/9_2.png) [@akrabat](https://discourse.slimframework.com/u/akrabat)\
**Post date:** [March 25, 2024, 4:21pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/2 "2024-03-25T16:21:16Z")

</div>

What is in your `composer.json` ?

---

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [March 25, 2024, 4:24pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/3 "2024-03-25T16:24:18Z")

</div>

i give you the longer. I tried an another version.

```auto
    "name": "gerard/slim-crud3",
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "authors": [
        {
            "name": "Gérard Le Rest",
            "email": "gerard.lerest@orange.fr"
        }
    ],
    "require": {
        "slim/slim": "^4.13",
        "slim/psr7": "^1.6",
        "php-di/php-di": "^7.0",
        "symfony/cache": "^6.4",
        "doctrine/dbal": "^4.0",
        "doctrine/orm": "^3.1",
        "doctrine/doctrine-bundle": "^2.12",
        "doctrine/cache": "^2.2",
        "doctrine/migrations": "^3.7"
    }
}
``
```

---

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [March 25, 2024, 7:14pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/4 "2024-03-25T19:14:57Z")

</div>

You didn’t answer to my question. Are the two documentation similar (v3 and v4?  
Isn’t it a problem to configure SLIM4 with Doctrine?

---

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [March 26, 2024, 9:53am UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/5 "2024-03-26T09:53:54Z")

</div>

I use PHP-DI and the example documentation use uma/dic  
. So i uninstall PHP-DI et and i install uma/dic. But it’ doesn’work/ Many underlines persist.  
Is it a good way?

---

<div class="post-metadata">

**Author:** ![odan](https://avatars.discourse-cdn.com/v4/letter/o/9de053/32.png) [@odan](https://discourse.slimframework.com/u/odan)\
**Post date:** [March 26, 2024, 10:17am UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/6 "2024-03-26T10:17:30Z")

</div>

It looks like `1ma/DIC` does not support autowiring, so better stick to PHP-DI.

> return $container;  
> ($routes = require **DIR**. ‘/routes.php’)($app);

This makes no sense to me, because the code after the return statement will not be executed, therefore the routes won’t be registered.

> require composer

This will also not work. Run `composer update` to download the latest dependencies instead.

---

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [March 26, 2024, 4:30pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/7 "2024-03-26T16:30:28Z")

</div>

You are right odan ($routes = require **DIR**. ‘/routes.php’)($app); after return is stupid.  
Thank you for your response, but keep uma/dic for the moment. It’s easier for me. I’m beginner in framwork. There are some errors in the documentation and the example. This is my bootstrap.php:

```auto
<?php
 
// bootstrap.php

use Doctrine\ORM\ORMSetup;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use UMA\DIC\Container;
use Doctrine\ORM\EntityManager;
use App\Service\UserService;

$container = new Container(require __DIR__. '/settings.php');
 
$container->set(EntityManager::class, static function (Container $c): EntityManager {
    /** @var array $settings */
    $settings = $c->get('settings');
 
    $config = ORMSetup::createAttributeMetadataConfiguration(
        $settings['doctrine']['metadata_dirs'],
        $settings['doctrine']['dev_mode'],
        null,
        $settings['doctrine']['dev_mode'] ?
            new ArrayAdapter() :
            new FilesystemAdapter(directory: $settings['doctrine']['cache_dir'])
    );
 
    return new EntityManager($settings['doctrine']['connection'], $config);
});

// définir un service dans un conteneur d'injection de dépendances.
$container->set(UserService::class, static function (Container $c) {
    return new UserService($c->get(EntityManager::class));
});

return $container;

```

three questions for the extract of the code:

```auto
// définir un service dans un conteneur d'injection de dépendances.
$container->set(UserService::class, static function (Container $c) {
    return new UserService($c->get(EntityManager::class));
``
- is this code correct?
- is it for the extract the good place?
- there is an error with Uservervice. I'm think the container set method is depreciated.
```

---

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [March 26, 2024, 5:17pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/8 "2024-03-26T17:17:45Z")

</div>

You’ve right odan, put code after a return is stupid. there are some errors in the documentation.  
this is my bootstrap.php. I’ve three questions.

```auto
?php
 
// bootstrap.php

use Doctrine\ORM\ORMSetup;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use UMA\DIC\Container;
use Doctrine\ORM\EntityManager;
use App\Service\UserService;

$container = new Container(require __DIR__. '/settings.php');
 
$container->set(EntityManager::class, static function (Container $c): EntityManager {
    /** @var array $settings */
    $settings = $c->get('settings');
 
    $config = ORMSetup::createAttributeMetadataConfiguration(
        $settings['doctrine']['metadata_dirs'],
        $settings['doctrine']['dev_mode'],
        null,
        $settings['doctrine']['dev_mode'] ?
            new ArrayAdapter() :
            new FilesystemAdapter(directory: $settings['doctrine']['cache_dir'])
    );
 
    return new EntityManager($settings['doctrine']['connection'], $config);
});

// définir un service dans un conteneur d'injection de dépendances.
$container->set(UserService::class, static function (Container $c) {
    return new UserService($c->get(EntityManager::class));
});

return $container;

```

- Is this code correct? (without UserDervice)

```auto
And about this abstract of the code

```

// définir un service dans un conteneur d’injection de dépendances.  
$container-\>set(UserService::class, static function (Container $c) {  
return new UserService($c-\>get(EntityManager::class));  
});

```auto
- Is the code at the correct place?
- UserSercice seems me to be depreciated. How can I change this piece of code.
Thank's a lot.
```

---

<div class="post-metadata">

**Author:** ![tj\_gumis](https://avatars.discourse-cdn.com/v4/letter/t/c89c15/32.png) [@tj\_gumis](https://discourse.slimframework.com/u/tj_gumis)\
**Post date:** [March 26, 2024, 6:30pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/9 "2024-03-26T18:30:47Z")

</div>

This is how I usually hook doctrine in my projects:

- dependencies definitions:

```auto
return [
    'entity-manager' => static function (
        ContainerInterface $container
    ): EntityManager {
        $config = ORMSetup::createAttributeMetadataConfiguration(
            paths: ($container->get('doctrine_orm'))['entities_paths'],
            isDevMode: $_ENV['APP_ENV'] === 'dev',
        );
        $config->setAutoGenerateProxyClasses(AbstractProxyFactory::AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED);
        $config->addCustomStringFunction(
            DqlFunctions\JsonExtract::FUNCTION_NAME,
            DqlFunctions\JsonExtract::class
        );
        $dsnParser = new DsnParser();
        $connectionParams = $dsnParser
            ->parse($_ENV['DB_URL']);
        $connectionParams['driver'] = 'pdo_mysql';
        $connection = DriverManager::getConnection(
            $connectionParams,
            $config
        );
        return new EntityManager($connection, $config);
    },

    'doctrine_orm' => [
        'entities_paths' => [
            './path/Entity',
        ],
    ],

    SomeRepositoryInterface::class => static function (
        ContainerInterface $container
    ): SomeRepository {
        return new SomeRepository(
            $container->get('entity-manager')
        );
    },
];

```

- composer.json :

```json
        "ext-pdo": "*",
        "doctrine/orm": "^2.11.0",
        "doctrine/dbal": "^3.2",
        "doctrine/annotations": "^2.0",

```

It’s just a copy/paste (hope I have not missed anything) but it should work with v4

---

<div class="post-metadata">

**Author:** ![odan](https://avatars.discourse-cdn.com/v4/letter/o/9de053/32.png) [@odan](https://discourse.slimframework.com/u/odan)\
**Post date:** [March 26, 2024, 6:32pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/10 "2024-03-26T18:32:39Z")

</div>

You are passing an callback function via the set method. This will not work, because this method requires a real instance. Again, please think about using PHP-DI, because UMA\DIC does not support what you are expecting, especially if you are starting with this topic. If you still want to keep UMA\DIC, then I would recommend to create an issue von [github](https://github.com/1ma/DIC/issues/new) with this specific question, because this is not a Slim specific issue.

---

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [March 26, 2024, 8:12pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/11 "2024-03-26T20:12:49Z")

</div>

Thanks you tj\_gumis for the examples of dependencies definitions. It will help me. Some configurations are complex. How do you define them? I want also understand what I can  
Odan, I am agree to use PHP-DI. But I prefer to repeat I am a beginner. I hope you’re patient. I begin to understand the notion of dependencies injection.  
I read the example of Dependency container. It seems simple. But where can i find good settings for EntityManager?

I have a question:

- for a route, i fetch likes this (Documentation):

```auto
$app->get('/foo', function (Request $request, Response $response, $args) {
    $myService = $this->get('myService');

```

and for a function alone, we inject dependency with the constructor ?

```auto
class StudentController
{
     private EntityManager $entityManager;

     public function __construct(EntityManager $entityManager)
     {
           $this->entityManager = $entityManager;
     }

```

Thanks a lot for your help.

```auto

```

---

<div class="post-metadata">

**Author:** ![tj\_gumis](https://avatars.discourse-cdn.com/v4/letter/t/c89c15/32.png) [@tj\_gumis](https://discourse.slimframework.com/u/tj_gumis)\
**Post date:** [March 27, 2024, 7:43am UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/12 "2024-03-27T07:43:46Z")

</div>

Do you want to learn something properly, or you just want to make it work?

---

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [March 27, 2024, 8:03am UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/13 "2024-03-27T08:03:51Z")

</div>

I want to learn something properly. But I hope it will not to be too complex.

---

<div class="post-metadata">

**Author:** ![tj\_gumis](https://avatars.discourse-cdn.com/v4/letter/t/c89c15/32.png) [@tj\_gumis](https://discourse.slimframework.com/u/tj_gumis)\
**Post date:** [March 27, 2024, 9:07am UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/14 "2024-03-27T09:07:19Z")

</div>

Why? If its simple, everyone can do it and you miss the whole fun and satisfaction 🙂

Btw, it is a bit complex for a newbie, but it is not complicated at all. If you got some programming basics I can guide you, otherwise you will end up discouraged.

---

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [March 27, 2024, 10:23am UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/15 "2024-03-27T10:23:08Z")

</div>

Ok.

 ![Capture d’écran du 2024-03-27 11-24-59](https://canada1.discourse-cdn.com/flex030/uploads/slimframework/original/2X/3/39b255ca6bb6556d6496d6d40880aa54ba0df072.png)  
The class StudentController has been generated by ChatGPT

this is my composer.json:

```json
{
    "name": "gerard/slim-crud3",
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "authors": [
        {
            "name": "Gérard Le Rest",
            "email": "gerard.lerest@orange.fr"
        }
    ],
    "require": {
        "slim/slim": "^4.13",
        "slim/psr7": "^1.6",
        "php-di/php-di": "^7.0",
        "symfony/cache": "^6.4",
        "doctrine/dbal": "^4.0",
        "doctrine/orm": "^3.1",
        "doctrine/doctrine-bundle": "^2.12",
        "doctrine/cache": "^2.2",
        "doctrine/migrations": "^3.7",
        "uma/dic": "^3.0"
    }
}

```

the index.php:

```php
<?php

// index.php

use Slim\Factory\AppFactory;

// Charger le fichier de configuration

require __DIR__. '/../vendor/autoload.php';

// Charger le fichier de configuration

require __DIR__. '/../config/bootstrap.php';

// Créer l'application Slim

$app = AppFactory::create();

//charger la route

(require __DIR__. '/../config/routes.php')($app);

$app->run(); // Démarre l'application

```

and bootstrap.php:

```php
<?php
 
// bootstrap.php

use Doctrine\ORM\ORMSetup;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use UMA\DIC\Container;
use Doctrine\ORM\EntityManager;
use App\Service\UserService;

$container = new Container(require __DIR__. '/settings.php');
 
$container->set(EntityManager::class, static function (Container $c): EntityManager {
    /** @var array $settings */
    $settings = $c->get('settings');
 
    $config = ORMSetup::createAttributeMetadataConfiguration(
        $settings['doctrine']['metadata_dirs'],
        $settings['doctrine']['dev_mode'],
        null,
        $settings['doctrine']['dev_mode'] ?
            new ArrayAdapter() :
            new FilesystemAdapter(directory: $settings['doctrine']['cache_dir'])
    );
 
    return new EntityManager($settings['doctrine']['connection'], $config);
});

// définir un service dans un conteneur d'injection de dépendances.
$container->set(UserService::class, static function (Container $c) {
    return new UserService($c->get(EntityManager::class));
});
``
return $container;

```

the settings.php:

````php
<?php

// settings.php

define('APP_ROOT', __DIR__ );

return [
    'settings' => [
        'slim' => [
            // Returns a detailed HTML page with error details and
            // a stack trace. Should be disabled in production.
            'displayErrorDetails' => true,

            // Whether to display errors on the internal PHP log or not.
            'logErrors' => true,

            // If true, display full errors with message and stack trace on the PHP log.
            // If false, display only "Slim Application Error" on the PHP log.
            // Doesn't do anything when 'logErrors' is false.
            'logErrorDetails' => true,
        ],

        'doctrine' => [
            // Enables or disables Doctrine metadata caching
            // for either performance or convenience during development.
            'dev_mode' => true,

            // Path where Doctrine will cache the processed metadata
            // when 'dev_mode' is false.
            'cache_dir' => APP_ROOT . '/var/doctrine',

            // List of paths where Doctrine will search for metadata.
            // Metadata can be either YML/XML files or PHP classes annotated
            // with comments or PHP8 attributes.
            'metadata_dirs' => [APP_ROOT . '/src/Domain'],

            // The parameters Doctrine needs to connect to your database.
            // These parameters depend on the driver (for instance the 'pdo_sqlite' driver
            // needs a 'path' parameter and doesn't use most of the ones shown in this example).
            // Refer to the Doctrine documentation to see the full list
            // of valid parameters: https://www.doctrine-project.org/projects/doctrine-dbal/en/current/reference/configuration.html
            'connection' => [
                'driver' => 'pdo_mysql',
                'host' => 'localhost',
                'port' => 3306,
                'dbname' => 'mydb',
                'user' => 'user',
                'password' => 'secret',
                'charset' => 'utf-8'
            ]
        ]
    ]
];
the routes.php:
```php
<?php

//routes.php

use App\Controllers\StudentController;
use Slim\App;

return function (App $app) {
    // Définition des routes
    $app->post('/create/student', StudentController::class . ':createStudent');
};

````

the StudentController.php:

```php
<?php

namespace App\Controllers;

//StudentController.php

use App\Entities\Student;
use Doctrine\ORM\EntityManager;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class StudentController
{

    private EntityManager $entityManager;

    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function createStudent(Request $request, Response $response, array $args): Response
    {
        $data = $request->getParsedBody();

        $student = new Student();
        if (isset($data['name'])) {
            $student->setName($data['name']);
        }
        if (isset($data['firstname'])) {
            $student->setFirstname($data['firstname']);
        }
        if (isset($data['age'])) {
            $student->setAge($data['age']);
        }

        $response->getBody()->write("étudiant rentré avec succès");

        try {
            // Utilisez $this->entityManager pour interagir avec la base de données
            $this->entityManager->persist($student);
            $this->entityManager->flush();

            $response->getBody()->write('Étudiant créé avec succès avec l\'ID : ' . $student->getId());
        } catch (\Exception $e) {
            $response->getBody()->write('Erreur lors de la création de l\'étudiant : ' . $e->getMessage());
            return $response->withStatus(500);
        }

        return $response->withHeader('Content-Type', 'application/json');
    }
}

```

Student.php:

```php
<?php

namespace App\Entities;

//Student.php

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table(name: "students")]
class Student
{
    #[ORM\Id]
    #[ORM\Column(type: "integer")]
    #[ORM\GeneratedValue]
    #[ORM\Column(nullable: false)]
    private $id;

    #[ORM\Column(type: "string", length: 50, nullable: false)]
    private $name;

    #[ORM\Column(type: "string", length: 50, nullable: false)]
    private $firstname;

    #[ORM\Column(type: "integer", nullable: false)]
    private $age;

    // Getter pour l'id
    public function getId()
    {
        return $this->id;
    }

    // Getter et setter pour le nom
    public function getName()
    {
        return $this->name;
    }

    public function setName($name): void
    {
        $this->name = $name;
    }

    // Getter et setter pour le prénom
    public function getFirstname()
    {
        return $this->firstname;
    }

    public function setFirstname($firstname): void
    {
        $this->firstname = $firstname;
    }

    // Getter et setter pour l'âge
    public function getAge()
    {
        return $this->age;
    }

    public function setAge($age): void
    {
        $this->age = $age;
    }
}

```

---

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [March 28, 2024, 3:21pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/18 "2024-03-28T15:21:38Z")

</div>

Good afternoon,

tj\_gumis, I’m always agree for your help. Have you an idea?

---

<div class="post-metadata">

**Author:** ![tj\_gumis](https://avatars.discourse-cdn.com/v4/letter/t/c89c15/32.png) [@tj\_gumis](https://discourse.slimframework.com/u/tj_gumis)\
**Post date:** [March 28, 2024, 8:03pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/19 "2024-03-28T20:03:23Z")

</div>

I sent you a private message a while ago 🙂

---

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [March 28, 2024, 8:34pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/20 "2024-03-28T20:34:32Z")

</div>

Ah, Ok! I understand why you deleted your message. It’ ok for me.  
Good evening!

---

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [April 7, 2024, 2:52pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/21 "2024-04-07T14:52:59Z")

</div>

I think after reading and progamming, I think I understand some things. I’m a beginner in framework, so, please be indulgent. I hope I don’t say stupid things.

**Last program:**

- It doesn’t have a good structure because I followed an old version of Doctrine.
- If I understand,the last program needs the doctrine console because the container uma/dic wich can’t do autowiring/  
The PHP-DI make it.

**The new program** (Slim - PHP-DI - Doctine) - it’s 's work.  
I have used:

- the excellent Odan tutorial: [Slim4-Tutorial](https://odan.github.io/2019/11/05/slim4-tutorial.html)  
and the good documentation (for me):
- The Odan’s slim4-book
- the good documentation (for me) of Doctrine:[Doctrine installation](https://www.doctrine-project.org/projects/doctrine-orm/en/2.19/reference/configuration.html)

**strong text** Secutiy and gestion management and error management are not implemented at the momet\*\*

Here are the programs:

- public/index: (tutorial code)

```php
<?php
(require __DIR__. '/../config/bootstrap.php')->run();

```

- config/bootstrap (code of the tutorial)

```php
use DI\ContainerBuilder;
use Slim\App;
 
require_once __DIR__. '/../vendor/autoload.php';
 
// Construire l'instance de container de type PHP-DI
$container = (new ContainerBuilder())
    ->addDefinitions( __DIR__. '/container.php')
    ->build();

 
// renvoyer l'instance du container
return $container->get(App::class);

```

- config/settings.php (personnal code)

```php
<?php
// settings.php
return [
    'doctrine' => [
        'pathToModels' => ' __DIR__. /../src/Models',
        'isDevMode' => true,
        'connectionMysql' => [
            'driver' => 'pdo_mysql',
            'dbname' => 'university',
            'user' => 'toto',
            'password' => 'mdp',
        ],
    ],
];

```

- config/container.php (tutorial code modified)

```php
<?php
 
use Slim\App;
use Slim\Factory\AppFactory;
use Doctrine\DBAL\DriverManager; 
use Doctrine\ORM\EntityManager; 
use Doctrine\ORM\ORMSetup;
use Psr\Container\ContainerInterface; 
 
return[
    'settings' => function () {
        $settings = require __DIR__. '/settings.php';
        return $settings;
    },
    // Construction de l'instance EntutyManager
    EntityManager::class => function (ContainerInterface $container) : EntityManager {
 
        $settings = (array)$container->get('settings')['doctrine'];
 
 
        $paths = [$settings['pathToModels']]; //chemin de l'entité
        $isDevMode = $settings['isDevMode']; // est-ce en développement?
 
        // paramètres de connexion
        $dbParams = $settings['connectionMysql']; //connexion de la base de données
 
        // construction er retour de l'instance AppFactory
        $config = ORMSetup::createAttributeMetadataConfiguration($paths, $isDevMode);
        $connection = DriverManager::getConnection($dbParams, $config);
        return new EntityManager($connection, $config);   
    },
 
    // construction de l'application $app
    App::class => function (ContainerInterface $container) {
        $app = AppFactory::createFromContainer($container);
 
        // Register routes
        (require __DIR__. '/routes.php')($app);
 
        // Register middleware
        (require __DIR__. '/middleware.php')($app);
 
        return $app;
    }
];

```

- config/routes.php (code personnal)

```php
<?php
 
use Slim\App;
use App\Controllers\StudentController;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
 
return function (App $app) {
    //route de test
    $app->get('/', function (Request $request, Response $response) {
        $response->getBody()->write('Hello, World!');
        return $response;
    });
    //Appel de la méthode createUser de la classe StudentContreller à l'aide de l'URL "localhost:8082/create/student"
    $app->post('/create/student', StudentController::class . ':createStudent');
};

```

- src/Contollers/StudentController.php (code perso)

```php
<?php
 
namespace App\Controllers;
 
use App\Models\Student;
use Doctrine\ORM\EntityManager;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
 
class StudentController
{
    private $entityManager;
 
    public function __construct(EntityManager $entityManager){
        $this->entityManager = $entityManager;
    }
 
    public function createStudent(Request $request, Response $response): Response
    {
        //récupération des données
        $data = $request->getParsedBody();
        error_log(print_r($data, true), 3, __DIR__. '/StudentController.log');
 
        // création des données de l'étudiant
        $student = new Student();
        $student->setName($data['name']);
        $student->setFirstname($data['firstname']);
        $student->setAge($data['age']);
 
        //transfert des données de l'étudiant dans la base de données
        $this->entityManager->persist($student);
        $this->entityManager->flush();
 
        $response->getBody()->write('Étudiant créé avec succès avec l\'ID :' . $student->getId());
        return $response->withHeader('Content-Type', 'application/json');
    } 
}

```

src/Models/student.php (personnal code):

```auto
<?php

namespace App\Models;

//Student.php

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Table(name: "students")]
class Student{

    #[ORM\Id]
    #[ORM\Column(type: "integer")]
    #[ORM\GeneratedValue]
    private $id;

    #[ORM\Column(type: "string", length: 50, nullable: false)]
    private $name;

    #[ORM\Column(type: "string", length: 50, nullable: false)]
    private $firstname;

    #[ORM\Column(type: "integer", nullable: false)]
    private $age;

    // Getter de l'Id
    public function getId()
    {
        return $this->id;
    }

    // Getter et setterde "name" 
    public function getName()
    {
        return $this->name;
    }

    public function setName($name): void
    {
        $this->name = $name;
    }

    // Getter et setter pour firstname
    public function getFirstname()
    {
        return $this->firstname;
    }

    public function setFirstname($firstname): void
    {
        $this->firstname = $firstname;
    }

    // Getter et setter pour "age"
    public function getAge()
    {
        return $this->age;
    }

    public function setAge($age): void
    {
        $this->age = $age;
    } 
}

```

```
I can hear your remarks.
I especially want to thank Daniel Opitz for his fabulous work.

```

---

<div class="post-metadata">

**Author:** ![samclia](https://avatars.discourse-cdn.com/v4/letter/s/ad7895/32.png) [@samclia](https://discourse.slimframework.com/u/samclia)\
**Post date:** [April 30, 2024, 1:00pm UTC](https://discourse.slimframework.com/t/doctrine-orm-documentation-v3-and-v4/5851/22 "2024-04-30T13:00:55Z")

</div>

the DI container definition Entitymanager does too much. So It’s preferable to create an another one for the connexion ([EntityManager and cache (slim 4) - #2 by odan](https://discourse.slimframework.com/t/entitymanager-and-cache-slim-4/5883/2))

```auto
// connexion à la base de données
    Connection::class => function (ContainerInterface $container) {
        $settings = (array)$container->get('settings')['doctrine'];
        // paramètres de connexion
        $dbParams = $settings['connectionMysql'];
        $config = $container->get('doctrineConfig');
        return DriverManager::getConnection($dbParams, $config);
    },

    //Configuration
    'doctrineConfig' => function (ContainerInterface $container) {
        $settings = (array)$container->get('settings')['doctrine'];
        return ORMSetup::createAttributeMetadataConfiguration(
            [$settings['pathToModels']], //chemin des l'entités
            $settings['isDevMode'] //est-on en développement?
        );
    },

    //EntityManager
    EntityManager::class => function (ContainerInterface $container) : EntityManager {
        $settings = (array)$container->get('settings')['doctrine'];
        $cache = $settings['isDevMode'] ?
            new ArrayAdapter() : 
            new FilesystemAdapter(directory: $settings['cache_dir']);
        $connection = $container->get(Connection::class); 
        $config = $container->get('doctrineConfig');
        return new EntityManager($connection, $config);

```
