Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get root dir in Symfony2

Tags:

php

symfony

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?

like image 518
user2515999 Avatar asked Jun 24 '13 11:06

user2515999


People also ask

How do I find the root directory path?

In order to get the root directory path, you can use _DIR_ or dirname(). echo dirname(__FILE__); Both the above syntaxes will return the same result.

How to get path in Symfony?

In Symfony AppKernel class is handling the project root directory under method getProjectDir() . To get it in the controller you can do: $projectRoot = $this->get('kernel')->getProjectDir(); it will return you a project root directory.

What is kernel root_ dir?

root_dir - which is actually the app/ directory where the AppKernel class lives. Anytime you need to reference a path in your project, use kernel. root_dir and build the path from it.

How do I root PHP?

In that case you could explode the string by slashes and return the first one: $pathInPieces = explode('/', $_SERVER['DOCUMENT_ROOT']); echo $pathInPieces[0]; This will output the server's root directory.


2 Answers

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.

like image 105
Jimbo Avatar answered Oct 16 '22 14:10

Jimbo


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%/../]
like image 38
Broncha Avatar answered Oct 16 '22 14:10

Broncha