Solved: How to get access to settings in Action class

Hi there,

I am new to slim framework and am currently building micro web service with latest version v4.3 and PHP 7.1.

My base is laying upon the https://github.com/slimphp/Slim-Skeleton app.

I mostly figured out how this thing operates but am having an issue with accessing the container from the action class.

Base on the routes.php it seems that preffered way to set action classes is to place the actual class name

return function (App $app) {
    $app->get('/login/{t}', MyAction::class);
};

However if I place some custom parameters to the constructor I get class this and that can not be resolved.

So how does one handle this?

Or do I just instantiate the object with correct parameters and pass that as callable?

The PSR-11 container implementation (PHP-DI) creates the objects for you.

https://akrabat.com/dependency-injection-in-slim-4/

OK,
In this specific case I did not need to specify anything in the container but it gave me the hint how to do it:

abstract class ApiAction extends Action
{
    /** @var array */
    protected $settings;

    /**
     * ApiAction constructor.
     * @param LoggerInterface $logger
     * @param ContainerInterface $c
     */
    public function __construct(LoggerInterface $logger, ContainerInterface $c)
    {
        parent::__construct($logger);
        $this->settings = $c->get('settings');
    }
}

Just I quick tip: The container should not passed to the action.

So what should be done instead?
I need those settings

A “container friendly” solution would be to declare a special Configuration / Config class as dependency in your constructor.

public function __construct(Config $config)
{
    $this->config = $config;
}

The Configuration object just needs to be defined and loaded like this:

$containerBuilder->addDefinitions([
    Config::class => function () {
       return new Config([
           'displayErrorDetails' => true,
            //...
       ]);
    },
]);

Edit: There are other configuration classes available of course:

3 Likes

Ok, this was helpful.

Thanks

Is this still the best practice in 2021? I went into your odan git repository and found the Configuration.php is already removed. Thank you!

When you declare an Config object the DI container can autowire this dependency. When you declare a config array you have to write a DI container definition (factory) manually for each class that requires some configuration key(s). On the other hand, objects that needs to be configured should be created within the DI container definition anyway. So in most cases an array is just “good enough”. From a higher level object-oriented code should use objects when possible. The downside of passing a Config object is that you may pass hundreds of other config keys and values that are never needed. The most libraries out here I know still use good old array for configuration.