Mouna Ben Hmida
Mouna Ben Hmida

Reputation: 375

symfony 4 : How to get "/public" from RootDir

I have an image under the public folder.
How can I get my image directory in symfony4 ?
In symfony 3, it's equivalent is :

$webPath = $this->get('kernel')->getRootDir() . '/../web/';

Upvotes: 28

Views: 71495

Answers (7)

Nexen
Nexen

Reputation: 114

In config/services.yaml:

parameters:
    webDir: '%env(DOCUMENT_ROOT)%'

In your controller:

use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

...

public function yourFunction(Parameterbag $parameterBag)
{
   $webPath = $parameterBag->get('webDir')
}

If you need to access a directory within public, change the last line to the following:

$webPath = $parameterBag->get('webDir') . '/your/path/from/the/public/dir/'

Upvotes: 7

Asenar
Asenar

Reputation: 7010

All above answers seems valid, but I think it's simplier if you configure it as parameter in services.yaml

If you need to use it in serveral services, you can bind it like this:

# services.yaml

services:
  _defaults:
    autowire: true
    autoconfigure: true
    bind:
      $publicDir: "%kernel.project_dir%/public"
# src/Services/MyService.php

class MyService
{
    public function __construct(
         private string $publicDir,
    ) {
    }

    // …
}

This way, this is configured at one place only, and if later you decide to change /public to something else, you will have to change it only in .yaml file.

If you don't need the root directory but a subdirectory, it might be better to define the final target path: This way you will be more flexible if you need later to move only that directory, like $imageDir or $imagePath (depends if you will use the full directory or only the public path).

Note also the default public path is defined in composer.json file, in the extra.public-dir key

Upvotes: 1

Az.Youness
Az.Youness

Reputation: 2652

Starting from Symfony 4.3 we can generate absolute (and relative) URLs for a given path by using the two methods getAbsoluteUrl() and getRelativePath() of the new Symfony\Component\HttpFoundation\UrlHelper class.

New in Symfony 4.3: URL Helper

public function someControllerAction(UrlHelper $urlHelper)
{
    // ...
    return [
        'avatar' => $urlHelper->getAbsoluteUrl($user->avatar()->path()),
        // ...
    ];
}

Upvotes: 2

Manolo
Manolo

Reputation: 26350

You can inject KernelInterface to the service or whatever and then get the project directory with $kernel->getProjectDir():

<?php

namespace App\Service;

use Symfony\Component\HttpKernel\KernelInterface;

class Foo
{
    protected $projectDir;

    public function __construct(KernelInterface $kernel)
    {
        $this->projectDir = $kernel->getProjectDir();
    }

    public function showProjectDir()
    {
        echo "This is the project directory: " . $this->projectDir;
    }
}

Upvotes: 5

Anjana Silva
Anjana Silva

Reputation: 9181

It is a bad practice to inject the whole container, just to access parameters, if you are not in a controller. Just auto wire the ParameterBagInterface like this,

protected $parameterBag;

public function __construct(ParameterBagInterface $parameterBag)
{
    $this->parameterBag = $parameterBag;

}

and then access your parameter like this (in this case the project directory),

$this->parameterBag->get('kernel.project_dir');

Hope someone will find this helpful.

Cheers.

Upvotes: 37

godrar
godrar

Reputation: 111

In Controller (also with inheriting AbstractController):

$projectDir = $this->getParameter('kernel.project_dir');

Upvotes: 10

goto
goto

Reputation: 8164

You can use either

$webPath = $this->get('kernel')->getProjectDir() . '/public/'; 

Or the parameter %kernel.project_dir%

$container->getParameter('kernel.project_dir') . '/public/';

Upvotes: 31

Related Questions