LuisF
LuisF

Reputation: 564

Symfony 4 - accessing parameters inside a Controller

I'm trying to get some parameters defined in the services.yaml into one of my controllers, but I can't seem to find anything that works.

The idea is that I want to have a common string inside all of my controllers that defines the prefix of all the routes inside my application, for example /api/v1/.

I'm trying to store that string inside the services.yaml file as it seems the appropriate place to do it.

Also, I would like to use the contents of these parameters inside the method annotation...

Any ideas?

Upvotes: 1

Views: 7197

Answers (3)

Florian Hermann
Florian Hermann

Reputation: 780

I don't think that accessing parameters from a service is the better choice. I will suggest you rather to define your parameter in the "bind" section of service.yaml file like this

services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false

        # Bind all arguments requested by multiple services (auto-wiring)
        bind:
            $yourParameter: '%your.parameter%'

Put a parameter in this bind section allows you to inject it like a service in all other services (including controllers).

Then in your controllers and all other services, you could do something like this:

class RandomController extends Controller
{
    private $yourParameter;

    public function __construct(string $yourParameter)
    {
        $this->yourParameter = $yourParameter;
    }
    ...

I answered your question about injecting parameters. Now if you want to use it in your route annotation, I would test something like this.

/**
 * @Route("/api/{apiVersion}/the/rest/of/your/route", name="route_name", defaults={"apiVersion"="%yourParameter%"})
 */
public function yourAction()
{}

I didn't test this last solution. Don't know if it still work with symfony 4. If not maybe try to put %$yourParameter% (with a '$'). Tell me about that.

Edit:

Or even better for you situation (I assume that you are using the annotation routing): I guess your parameter is important only for the /api/ part of your application. Then you can define in your config/routes/annotations.yaml file all your controller concerned by your api. I suggest something like this.

controllers:
    path: /api/{apiVersion}
    resource: ../../src/Controller/Api
    type: annotation
    defaults:
        apiVersion : '%your.parameter%'
    # And maybe add also requirements like this
    requirements:
        apiVersion: 'v0|v1|v2'

Where all your api controllers are in the src/Controller/Api folder. Therefore, this solution allows you to define this configuration only once.

Upvotes: 1

Vyctorya
Vyctorya

Reputation: 1438

If you don't want to inject the parameter you can use this:

$this->getParameter('your.parameter');

service.yaml

parameters:
    your.parameter: /api/v1/

Upvotes: 4

Mike Doe
Mike Doe

Reputation: 17624

Starting from Symfony 4.1 you will be able to wire container parameters automatically.

For now you have to explicitly tell the dependency injection component how to wire such property. You can create a service for that to have it autowired everywhere you want:

namespace App\Provider;

final class DefaultEndpointProvider
{
    private $url;

    public function __construct(string $url)
    {
        $this->url = $url;
    }

    public function getUrl()
    {
        return $this->url;
    }
}

service definition:

# todo: replace with parameter bind in Sf4.1
App\Provider\DefaultEndpointProvider:
  arguments:
    $url: '%common_url_parameter%'

then you can simply require that service as a dependency in your controllers / services etc.

Upvotes: 4

Related Questions