Symfony 4, get the root path of the project from a custom class (not a controller class)

后端 未结 4 1214
孤街浪徒
孤街浪徒 2020-12-30 03:56

In the src/Utils directory, I created a custom class Foo for various things. I\'m looking for a way to get the absolute root path of the symfony 4 project <

相关标签:
4条回答
  • 2020-12-30 04:32

    If your class is extending: Symfony\Bundle\FrameworkBundle\Controller\AbstractController, then you can get the root dir as

    $projectRoot = $this->getParameter('kernel.project_dir');
    

    or

    Inject ContainerBagInterface to your controller

    protected $projectRoot;
    
    public function __construct(ContainerBagInterface $containerBag)
    {
        $this->projectRoot = $containerBag->get('kernel.project_dir');;
    }
    

    or

    Even better and the recommended approach

    Inject the root_dir to your Foo class. Add the following to your config under services

    services:
        foo:
            class:     App\Path\To\Foo
            arguments: ['%kernel.root_dir%']
    

    The container should pass the argument to your class on resolving, the Foo class should look like this

    <?php
    
    namespace App\Path\To;
    
    class Foo {
    
      private $rootDir;
    
      public function __construct($rootDir) 
      {
         $this->rootDir = $rootDir;
      }
    }
    
    0 讨论(0)
  • 2020-12-30 04:36

    In Symfony AppKernel class is handling the project root directory under method getProjectDir(). To get it in the controller you can do:

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

    it will return you a project root directory.

    If you need the project root directory in one of your classes you have two choices which I will present to you. First is passing AppKernel as dependency:

    class Foo 
    {
        /** KernelInterface $appKernel */
        private $appKernel;
    
        public function __construct(KernelInterface $appKernel)
        {
            $this->appKernel = $appKernel;
        }
    }
    

    Thanks to Symfony 4 autowiring dependencies it will be autmomaticaly injeted into your class and you could access it by doing:

    $this->appKernel->getProjectDir();
    

    But please notice: I don't think it's a good idea, until you have real need and more to do with AppKernel class than getting the project root dir. Specially if you think later on creating about unit tests for your class. You would automatically increase complexity by having a need to create mock of AppKernel for example.

    Second option and IMHO better would be to pass only a string with path to directory. You could achieve this by defining a service inside config/services.yaml like this:

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

    and your constructor would look like:

    class Foo 
    {
        /** string $rootPath */
        private $rootPath;
    
        public function __construct(string $rootPath)
        {
            $this->rootPath = $rootPath;
        }
    }
    
    0 讨论(0)
  • 2020-12-30 04:40

    This is work :

    // 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 讨论(0)
  • 2020-12-30 04:49

    Without 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 讨论(0)
提交回复
热议问题