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?
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.
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.
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.
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.
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.
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();
}
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%/../]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With