web-dev-qa-db-fra.com

Symfony 4, obtenez le chemin racine du projet à partir d'une classe personnalisée (pas une classe contrôleur)

Dans le répertoire src/Utils, j'ai créé une classe personnalisée Foo pour diverses choses. Je cherche un moyen d'obtenir le chemin racine absolu du projet symfony 4

Depuis un contrôleur, c'est facile avec:

$webPath = $this->get('kernel')->getProjectDir();

Mais à partir d'une classe personnalisée que j'ai créée dans mon répertoire src/Utils, comment puis-je obtenir le répertoire du chemin racine?

Je pourrais passer le chemin du contrôleur à la classe Foo:

$webPath = $this->get('kernel')->getProjectDir();
$faa = new Foo($webPath);
$faa->doSomething();

mais je pense qu'il est plus approprié de stocker ces informations dans la classe Foo et d'avoir uniquement une "logique de contrôleur" dans la classe de contrôleur

10
matthieu lopez

Dans Symfony, la classe AppKernel gère le répertoire racine du projet sous la méthode getProjectDir(). Pour l'obtenir dans le contrôleur, vous pouvez faire:

$projectRoot = $this->get('kernel')->getProjectDir();

il vous renverra un répertoire racine du projet.

Si vous avez besoin du répertoire racine du projet dans l'une de vos classes, vous avez deux choix que je vais vous présenter. Le premier passe AppKernel comme dépendance:

class Foo 
{
    /** KernelInterface $appKernel */
    private $appKernel;

    public function __construct(KernelInterface $appKernel)
    {
        $this->appKernel = $appKernel;
    }
}

Grâce aux dépendances de câblage automatique de Symfony 4, il sera automatiquement injecté dans votre classe et vous pourrez y accéder en faisant:

$this->appKernel->getProjectDir();

Mais veuillez noter: Je ne pense pas que ce soit une bonne idée, jusqu'à ce que vous ayez vraiment besoin et plus à faire avec la classe AppKernel que d'obtenir le répertoire racine du projet. Surtout si vous pensez plus tard à créer des tests unitaires pour votre classe. Vous augmenteriez automatiquement la complexité en ayant un besoin de créer une maquette de AppKernel par exemple.

La deuxième option et à mon humble avis serait de ne transmettre qu'une chaîne avec le chemin vers le répertoire. Vous pouvez y parvenir en définissant un service dans config/services.yaml comme ça:

services:
    (...)
    MyNamespace\Foo:
        arguments:
            - %kernel.project_dir%

et votre constructeur ressemblerait à:

class Foo 
{
    /** string $rootPath */
    private $rootPath;

    public function __construct(string $rootPath)
    {
        $this->rootPath = $rootPath;
    }
}
4
Tomasz

Sans Kernel injection

config/services.yaml

services:
    _defaults:
        autowire: true
        autoconfigure: true
        bind:
            $projectDir: '%kernel.project_dir%'

....

class Foo
{
    private $projectDir;

    public function __construct(string $projectDir)
    {
        $this->projectDir = $projectDir;
    }
}
0
Artem

C'est du travail:

// from Foo class
use Symfony\Component\HttpKernel\KernelInterface;
...
class Foo{
    private $rootDir;
    public function __construct(KernelInterface $kernel)
    {
        $this->rootDir = $kernel->getProjectDir();
    }
    public function myfoomethod(){
        return $this->getRootDir();
    }
    public function getRootDir(){
        return $this->rootDir;
    }
}


// from the controller class 
use App\Utils\Foo;
...
class FaaController extends AbstractController
{
    /**
     * @Route("/scenario", name="scenario")
     */
    public function new(Foo $foo)
    {
        dump($foo->myfoomethod()); //show the dir path !
        return $this->render('faa/index.html.twig');
    }
}
0
user2137454