How to access settings inside route callable

Hi guys,

I’m using Slim 4 and I want to access settings from inside class method in route.
Here is the code:

in routes.php:
$app->get(’/test’, TestCallable::class . ‘:testMethod’);

in TestCallable class:
declare(strict_types=1);

namespace App\Application\Middleware;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;

class TestCallable {
public function __construct() {}

public function testMethod(Request $request, Response $response): Response {
    /// HERE I WANT TO ACCESS settings
    $response->getBody()->write('Test method');
    return $response;
}

}

in settings.php (added after default ‘logger’ section):
‘test’ => [
‘s1’ => ‘val1’,
‘s2’ => ‘val2’
]

Is there any documentation or example how to achieve this?

Best regards,
Nikolay

What is best depends on what you’re trying to achieve, it’s possible a service or middleware might be a better alternative and it’s likely that what you want to achieve could be done with autowiring.

You can make the settings variable available in the scope of the callable and add a use-declaration.

function foo($req, $res) use ($settings) {}

  1. Dependency declaration - set your logger settings parameters as your testClass attribute and inject these settings as dependency injection (you need to declare explicitly your testClass instantiation definition).
  2. Route declaration - set your logger settings parameters as your testClass’s testMethod third parameter and send them from within route definition directly where is actually needed - possibly better choice.
1 Like

Hello, chechy!

I didn’t have time to test it but this is the idea.

You define the name ‘settings’ in the Dependecy Injection Container, put in the constructor in the TestCallable class that receives a ContainerInterface and Slim will magically inject the Container into the class.

// in routes.php:
$app->get(’/test’, TestCallable::class . ‘:testMethod’);


// in TestCallable class:

declare(strict_types=1);

namespace App\Application\Middleware;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Psr\Container\ContainerInterface;

class TestCallable {
private $settings;

public function __construct(ContainerInterface $container) {
    $this->settings = $container->get('settings');
}

public function testMethod(Request $request, Response $response): Response {
    /// HERE I WANT TO ACCESS settings
    $this->settings['test']['s1'];

    $response->getBody()->write('Test method');
    return $response;
}

}


// in app/settings.php:
declare(strict_types=1);

use DI\ContainerBuilder;

return function (ContainerBuilder $containerBuilder) {
$containerBuilder->addDefinitions([
‘settings’ => [ ‘test’ => [‘s1’ => ‘val1’, ‘s2’ => ‘val2’ ]],
]);
/*
// If you define a complete class path, as below,
// and you place this same class in the constructor of an Action (Controller),
// Slim automatically injects too.

$containerBuilder->addDefinitions([
    Psr\Log\LoggerInterface::class => [
        'test' => [
            's1' => 'val1',
            's2' => 'val2'
            ]
    ],
]);

*/

};


//in public/index.php

use DI\ContainerBuilder;


// Instantiate PHP-DI ContainerBuilder
$containerBuilder = new ContainerBuilder();
if (false) { // Should be set to true in production
$containerBuilder->enableCompilation(DIR . ‘/…/var/cache’);
}
// Set up settings
$settings = require DIR . ‘/…/app/settings.php’;
$settings($containerBuilder);

// Build PHP-DI Container instance
$container = $containerBuilder->build();

// Instantiate the app
AppFactory::setContainer($container);
$app = AppFactory::create();
$callableResolver = $app->getCallableResolver();