Symfony 4,从自定义类(而非控制器类)获取项目的根路径

时间:2018-10-17 08:32:15

标签: php symfony4

在src / Utils目录中,我为各种事情创建了一个自定义类 Foo 。我正在寻找一种获取symfony 4项目的绝对根路径的方法

从控制器开始,它很容易:

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

但是从我在src / Utils目录中创建的自定义类中,如何获取根路径目录?

我可以将路径从控制器传递到 Foo 类:

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

但是我认为将这些信息存储在Foo类中并且在控制器类中仅包含“控制器逻辑”是更合适的

4 个答案:

答案 0 :(得分:12)

不进行Kernel注入

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;
    }
}

答案 1 :(得分:6)

在Symfony AppKernel中,类正在处理方法getProjectDir()下的项目根目录。要将其放入控制器中,您可以执行以下操作:

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

它将返回您的项目根目录。

如果您需要在一个类中使用项目根目录,则有两种选择,我将向您提供两种选择。首先是将AppKernel作为依赖项传递:

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

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

由于Symfony 4自动装配的依赖关系,它将自动注入到您的班级中,您可以通过以下方式访问它:

$this->appKernel->getProjectDir();

但是请注意:我认为这不是一个好主意,除非您有真正的需求并且与AppKernel类有更多关系,而不是获得项目根目录。特别是如果您稍后考虑为您的班级创建单元测试。例如,您需要创建AppKernel的模拟对象,从而自动增加复杂性。

第二个选项和恕我直言,更好的方法是只传递带有目录路径的字符串。您可以这样在config/services.yaml内定义服务来实现此目的:

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

您的构造函数将如下所示:

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

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

答案 2 :(得分:5)

如果您的课程正在扩展: Symfony\Bundle\FrameworkBundle\Controller\AbstractController,则可以将根目录获取为

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

向您的控制器注入ContainerBagInterface

protected $projectRoot;

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

更好,更推荐的方法

root_dir注入您的Foo类。将以下内容添加到“服务”下的配置中

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

容器在解析时应将参​​数传递给您的类,Foo类应如下所示

<?php

namespace App\Path\To;

class Foo {

  private $rootDir;

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

答案 3 :(得分:0)

这是工作:

// 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');
    }
}