Micro-Framework Slim / ORM Doctrine

- Classes absentes dans le dossier vendor

a marqué ce sujet comme résolu.

C’est mon premier message sur ce forum. Bonjour à tous!

J’ai installé Slim et testé un CRUD sans soucis. Je suis novice dans les framework.

Je veux installer l’ORM Doctrine d"après le tuturiel suivant:

https://www.slimframework.com/docs/v4/cookbook/database-doctrine.html

Dans le fichier bootstrap.php (partie Define the EntityManager service) , j’ai des soulignements "Undefined type".

Voici le soulignements: boostrap

et le fichier accessible.

<?php

namespace App\config;
// bootstrap.php

use Doctrine\Common\Cache\Psr6\DoctrineProvider;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Setup;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use UMA\DIC\Container;

$container = new Container(require __DIR__ . '/settings.php');

$container->set(EntityManager::class, static function (Container $c): EntityManager {
    /** @var array $settings */
    $settings = $c->get('settings');

    // Use the ArrayAdapter or the FilesystemAdapter depending on the value of the 'dev_mode' setting
    // You can substitute the FilesystemAdapter for any other cache you prefer from the symfony/cache library
    $cache = $settings['doctrine']['dev_mode'] ?
        DoctrineProvider::wrap(new ArrayAdapter()) :
        DoctrineProvider::wrap(new FilesystemAdapter(directory: $settings['doctrine']['cache_dir']));

    $config = Setup::createAttributeMetadataConfiguration(
        $settings['doctrine']['metadata_dirs'],
        $settings['doctrine']['dev_mode'],
        null,
        $cache
    );

    return EntityManager::create($settings['doctrine']['connection'], $config);
});

return $container;


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

  • Les importations de classes semblent bonnes (non souligné). Mais par exemple, je ne retrouve pas dans vendor le dossier Symfony/Component. Il y a d’autres dossiers et classes absentes.

et le composer.json:

{
    "autoload": {
        "psr-4": {
            "App": "src/"
        }
    },
    "require": {
        "slim/slim": "4.*",
        "slim/psr7": "^1.6",
        "doctrine/orm": "^3.1",
        "symfony/cache": "^6.4",
        "php-di/php-di": "^7.0"
    }
}

J’ai essayé de supprimer le dossier vendor et composer.lock

rm -rf vendor/ composer.lock

puis:

composer require

mais sans succès. Cela ne fonctioone pas non plus sur PhpStorm.

Merci pour votre aide.

+0 -0

Je viens de constater aujourd’hui que les documentations v3 et v4 sur l’utilisation de doctrine sont similaires, sauf erreur de ma part.

  • v4
  • v3 La question que je me pose: Est-ce que la documentation de doctrine(V3) permet de faire fonctionner SLIM4 avec Doctrine? Si ce n’est pas le cas, cela expliquerait les absences des classes Qu’en pensez-vous?

PS; j’ai posé la question sur le forum de Slim. On m’a juste demandé mon composer.json. C’est tout. Je vais en demander plus.

+0 -0

Salut

Il m’est arrivé, avec des projets Composer, que l’outil d’analyse de code n’ait pas pris les dépendances en compte, parce qu’il indexe le code à l’ouverture du projet sinon de l’éditeur. Avec VS Code, il me semble que recharger la fenêtre pourrait fonctionner, en tout cas ça fonctionnait jusqu’à il n’y a pas longtemps. Qu’en est-il chez toi ?

Je ne connais pas assez PhpStorm pour savoir ce qu’il en est, mais je ne serais pas nécessairement étonné que ce soit la même chose.

+0 -0

Hello :) . Tu peux donner l’erreur précise que te sors PHPStorm ? Si tu n’as pas de dossier symfony/cache dans ton dossier vendor c’est en effet un soucis.

Essaie la commande composer install plutôt que composer require ;) .

Bonjour, Je travaille sous VSCode. Symfony/cache est installé. Leur documentation n’est pas à jour, et certains paquets sont obsolètes. Je suis en contact avec le forum de Slim. Ils me conseillent d’utiliser un conteneur de PHP-DI au lieu d’"uma/dic". l' uma.dic ne supporte pas l’autowiring (?). Leur site est plutôt réactif. Je préfère ne pas courir dix lièvres à la fois. Merci pour ton aide. Je n’hésiterais pas à passe si besoin. Dans tous les cas, je te fais un retour.

+0 -0

Bonjour à tous,

Comme promis, me revoilà! Je pense avoir compris un certain nombre de choses. J’espère ne pas trop dire de bétises. Je rappelle que je suis novice en framework. Donc j’espère que vous serez indulgent avec mes erreurs.

Ancien programme

  • Le programme précédent n’avait pas la bonne structure et se référait à une ancienne documentation Docrine.
  • le conteneur uma/dic ne gère pas l’autowire et doit être aidé par la console pour trouver les injections à effectuer. Voici une documentation avec du code obsèlte mais qui décrit bien l’utilité de la console: console Ce qui n’est pas le cas de d’un containeur PH-DI. Les injections se font automatiquement, lorsque cela est demandé dans le programme

Nouveau programme Voici les deux documents de référence qui m’ont servi à faire mon programme.

  • un excellent tutoriel qui décrit la construction d’un programme PHP-DI et qui m’a appris beaucoup de choses. [tutoriel](https://odan.github.io/2019/11/05/slim4-tutorial.html. Il est à joour contrairement à la documentation slim qui n’est pas à jour. Je l’ai testé sans problème) L’auteur attache aussi beaucoup d’importance à bien structurer son programme. Il l’explique au fur et à mesure. Ce qui est génial pour un novice comme moi. Avec quelques connaissances sur l’injection des dépendances, ce tutoriel est vraiment une référence
  • documentation doctrine:doc doctrine

Voici les programmes qui ont permit d’installer le servcie EntityManager dans le programme pour pouvoir à partir de données JSON générées par POSTMAN et de les de les enregistrer dans une base de données "users" (OPFDoction. Voici la structure json à trairer { "nom": "Dupont", "age": 30, "estEmploye": true }

Je n’ai pas encore gérer la sécurité et les erreurstext**

Voici les programmes:

  • public/index: (tutorial code)
<?php
(require __DIR__ . '/../config/bootstrap.php')->run();
  • config/bootstrap (code of the tutorial)
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',
        ],
    ],
];
  • container.php (tutorial code modified)
<?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 code)
<?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/Controllers/ControllerStudent.php (personnal code):
<?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)
<?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;
```<?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;
    } 
}

Vos remarques sont es bienvenues. Merci pour votre lecture! Et bonne fin de journée.

+0 -0

D’après Odan (Daniel Opitz), la définition de conteneur DI (je ne sais si c’est la bonne traduction) Entitymanager en fait trop. Il vaut mieux en créer une pour la connexion: (https://discourse.slimframework.com/…he-slim-4/5883)

// 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);
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte