Symfony 4,从自定义类(不是控制器类)获取项目的根路径
Posted
技术标签:
【中文标题】Symfony 4,从自定义类(不是控制器类)获取项目的根路径【英文标题】:Symfony 4, get the root path of the project from a custom class (not a controller class) 【发布时间】:2019-03-21 20:58:42 【问题描述】:在 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 类中并且在控制器类中只有“控制器逻辑”更合适
【问题讨论】:
将此值作为参数传递给 Foo 类 constructor,它将自动装配。 嗯,可以给我提供一个构造方法的例子吗? 【参考方案1】:这是工作:
// 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');
【讨论】:
但@Tomasz 的回答更好;) 很高兴您包含了使用声明 确实,没有其他解决方案提到use Symfony\Component\HttpKernel\KernelInterface
,但没有它就什么都行不通【参考方案2】:
在 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;
【讨论】:
对于第一个解释,您还应该提到在类文件上方包含use Symfony\Component\HttpKernel\KernelInterface;
。【参考方案3】:
没有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;
【讨论】:
官方文档中的解决方案:symfony.com/blog/new-in-symfony-4-2-important-deprecations【参考方案4】:如果您的课程正在扩展:
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.project_dir%']
容器应在解析时将参数传递给您的类,Foo
类应如下所示
<?php
namespace App\Path\To;
class Foo
private $projectDir;
public function __construct($projectDir)
$this->projectDir = $projectDir;
【讨论】:
在 2019/2020/2021 年,使用当前版本的 Symfony (4,5+) 这是执行此操作的方法。 最后一个例子对我很有效。但是,我不得不将%kernel.root_dir%
更改为%kernel.project_dir%
。以上是关于Symfony 4,从自定义类(不是控制器类)获取项目的根路径的主要内容,如果未能解决你的问题,请参考以下文章
如何在模块化的 java 11 应用程序中动态加载 Libreoffice jar,而不从自定义类加载器中获取 ClassCastException