我正在尝试获取 symfony2 中的根目录。
如果我使用:
$this->get('kernel')->getRootDir();
我收到此错误:
FatalErrorException: Error: Call to undefined method Test\Component\ClassLoader\DebugClassLoader::get()
我怎样才能解决这个问题?
编辑,因为这篇文章引起了如此多的关注,而我的在顶部,获取根目录的最佳方法是将它作为构造函数参数传递给你的类。您将使用它
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
}
}
下面的其余答案是不使用依赖注入的旧的、糟糕的方法。
我想让每个人都知道这是Service Locator,它是一种反模式。任何开发人员都应该能够仅从方法签名中看到类或控制器需要什么才能发挥作用。注入整个“容器”非常通用,难以调试,也不是最好的处理方式。你应该使用一个依赖注入容器,它允许你在应用程序的任何地方注入你想要的东西。请明确点。查看一个非常棒的递归实例化依赖注入容器,称为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();
}
如果要从服务访问容器,则必须将控制器定义为服务。您可以在这篇文章、这篇文章和这篇文章中找到有关如何执行此操作的更多信息。另一个有用的链接。无论哪种方式,您现在都知道要寻找什么了。这篇文章也可能有用:
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"]
您可以在docs中阅读有关服务容器的更多信息。
参数kernel.root_dir
指向app
目录。通常要进入根目录,我使用kernel.root_dir
/../
所以在控制器中你可以使用$this->container->getParameter('kernel.root_dir')."/../"
在服务定义中,您可以使用:
my_service:
class: \Path\to\class
arguments: [%kernel.root_dir%/../]
最好的选择是在您的 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;
}
}