【问题标题】:How to get root dir in Symfony2如何在 Symfony2 中获取根目录
【发布时间】:2013-06-24 11:10:59
【问题描述】:

我正在尝试获取 symfony2 中的根目录。

如果我使用:

$this->get('kernel')->getRootDir();

我得到这个错误:

FatalErrorException: Error: Call to undefined method Test\Component\ClassLoader\DebugClassLoader::get() 

我该如何解决这个问题?

【问题讨论】:

  • 你在哪里调用这个代码?在控制器内?
  • 是的,进入一个控制器,但是之前,我试图把这个函数调用到另一个类中。

标签: php symfony


【解决方案1】:

编辑,鉴于这篇文章引起了如此多的关注,而我的文章在顶部,获取根目录的最佳方法是将其作为构造函数参数传递给您的类。您将使用 services.yml 来执行此操作,并在参数中:

serviceName:
  class: Name\Of\Your\Service
  arguments: %kernel.root_dir%

然后,以下代码将在框架实例化它时将根目录分配给它:

namespace Name\Of\Your;

class Service
{
    public function __construct($rootDir)
    {
        // $rootDir is the root directory passed in for you
    }
}

下面的其余答案是不使用依赖注入的旧的、糟糕的方法。


我想让每个人都知道这是服务定位器,它是一种反模式。任何开发人员都应该能够通过方法签名了解类或控制器需要什么才能发挥作用。注入整个“容器”非常通用,难以调试并且不是最好的做事方式。您应该使用依赖注入容器,它允许您在应用程序的任何位置专门注入您想要的东西。请明确点。查看一个 seriously awesome 递归实例化依赖注入容器 Auryn。在您的框架解析您的控制器/动作的地方,将其放置在那里并使用容器来创建控制器并运行该方法。繁荣!即时 SOLID 代码。

你是对的,服务容器是使用$this->get('service')访问的。

但是,为了使用$this->get(),您需要访问get() 方法。

控制器访问

通过确保您的控制器扩展了 Symfony 使用的基本控制器类,您可以访问这个以及许多其他方便的方法。

确保您引用了正确的 Controller 基类:

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class HelloController extends Controller
{
    /** The Kernel should now be accessible via the container **/
    $root = $this->get('kernel')->getRootDir();
}

服务访问

如果你想从服务访问容器,你将不得不define your controller as a service。您可以在this postthis postthis post 中找到有关如何执行此操作的更多信息。另一个useful link。无论哪种方式,您现在都知道要寻找什么了。 This post 也可能有用:

use Symfony\Component\DependencyInjection\ContainerInterface; 

class MyClass
{
    private $container;

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

    public function doWhatever()
    {
        /** Your container is now in $this->container **/
        $root = $this->container->get('kernel')->getRootDir();
    }
}

在你的 config.yml 中,定义你的新类型:

myclass:
  class: ...\MyClass
  arguments: ["@service_container"]

您可以在the docs 中阅读有关服务容器的更多信息。

【讨论】:

  • 谢谢,但如果我想访问 $this->get... 不在控制器中,否则在另一个类中,我该怎么做?谢谢
  • @user2515999 我已经更新了代码。您需要使用 ContainerInterface。
  • 将容器传递给服务是一种不好的做法!
  • @Shady 您是否阅读了顶部的部分:我想让每个人都知道这是服务定位器,它是一种反模式。??跨度>
【解决方案2】:

参数kernel.root_dir指向app目录。通常要进入根目录,我使用kernel.root_dir/../

所以在控制器中你可以使用$this->container->getParameter('kernel.root_dir')."/../"

在服务定义中你可以使用:

my_service:
    class: \Path\to\class
    arguments: [%kernel.root_dir%/../]

【讨论】:

  • 如果您只需要根应用程序目录,请使用这种方式 - 仅将这个参数 %kernel.root_dir% 注入您的服务。
【解决方案3】:

最好的选择是在你的 services.yml 文件中将旅游类声明为服务:

services:
    myclass:
        class: Your\Class\Namespace\MyClass
        arguments: ["@service_container"]

并调整你的类的构造函数:

use Symfony\Component\DependencyInjection\ContainerInterface

class MyClass
{
    private $container;

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

【讨论】:

  • 注入洞容器是一种不好的做法!
猜你喜欢
  • 2012-03-02
  • 2014-06-03
  • 1970-01-01
  • 2014-03-29
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多