简体   繁体   中英

How to get root dir in Symfony2

I'm trying to get the root dir in symfony2.

If I use:

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

I get this error:

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

How can I fix this?

Edit, seeing as this post has garnered so much attention and mine is at the top, the best way to get the root directory is to pass it in to your class as a constructor argument. You would use services.yml to do this, and in arguments:

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

Then, the following code will have the root directory given to it when the framework instantiates it:

namespace Name\Of\Your;

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

The rest of the answer below is the old, poor way of doing it without using Dependency Injection.


I want to make everyone aware that this is the Service Locator , which is an anti-pattern . Any developer should be able to see what a class, or controller, requires to function from the method signature only . Injecting a whole "container" is very generic, hard to debug and isn't the best way of doing things. You should use a Dependency Injection Container that allows you to inject specifically what you want anywhere in your application. Be specific. Check out a seriously awesome recursively instantiating dependency injection container called Auryn . Where your framework resolves your controller / action, place it there and use the container to create the controller and run the method instead. Boom! Instant SOLID code.

You're correct, the service container is accessed using $this->get('service') .

However, in order to use $this->get() , you're going to need access to the get() method.

Controller Access

You gain access to this, and many other handy methods, by making sure your controller extends the base controller class that Symfony uses.

Make sure you're referencing the correct Controller base class:

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

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

Service Access

If you want to access the container from a service, you're going to have to define your controller as a service . You can find more information in this post , this post and this post about how to do this. Another useful link . Either way, you now know what to look for. This post may also be useful:

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

In your config.yml, define your new type:

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

You can read more about the service container in the docs .

The parameter kernel.root_dir points to the app directory. Normally to get to the root directory, I user kernel.root_dir /../

So in controller you can use $this->container->getParameter('kernel.root_dir')."/../"

In service definition you can use:

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

The best option is to declare tour class as a service in your services.yml file:

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

and adapt yhe constructor of you class:

use Symfony\Component\DependencyInjection\ContainerInterface

class MyClass
{
    private $container;

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM