DI Container and settings

Hi @odan I am learning to use slim 4 and I have a confusion with loading the configured values ​​in the container, I did it as you show here: https://github.com/odan/slim4-tutorial/blob/master/config/container .php.
However, I don’t see a way to extract the values, nor how to set those values ​​within the settings.php file. Can you give me help with that?
Thank you

To get the settings within a DI container definition you can use this example:

$settings = $container->get('settings');

Hi @odan, I used it like this in my route, but I get an error: variable $container is undefined

To get the settings within a Route callback you can use this example:

$settings = $this->get('settings');

Hola Odan, aún no me ha funcionado lo del contenedor, no encuentro la forma de usar las configuraciones que tengo en el contendor en las clases donde las necesito.
Si alguno me puede ayudar con un ejemplo más claro se los agredezco.
muchas gracias

Hello Odan, I already managed to obtain the configuration saved in the container in the routes, but now I need to receive them in a class. As I would do it?

How get DI container into class in Slim 4

The DI container should not passed around within the application. To read settings within a class you could let the DI container pass theses settings as an “Config” object or you pass them manually within a DI container definition.

Hi @odan, do you have any example that guides me how I should do it?

First you need an Config class that holds the config keys and values. Then you are able to declare that Config object via the class constructor.

The most simple Config class could be implemented as follows:

<?php

namespace App\Support;

use ArrayObject;

final class Config extends ArrayObject
{

}

This class is just “empty” because it needs no custom implementation, but the “unique” class name is needed for dependency injection and autowiring.

Then add a new DI container definition for the “Config” class to populate it with the settings.

use App\Support\Config;
// ...

return [
    'settings' => function () {
        return require __DIR__ . '/settings.php';
    },

    Config::class => function (ContainerInterface $container) {
        return new Config($container->get('settings'));
    },
];

Now you just need to declare the Config class within the class constructor where it is needed. Example.

<?php

namespace App\Example;

use App\Support\Config;

final class MyExample
{
    private Config $config;
    
    public function __construct(Config $config)
    {
        $this->config = $config;
    }
    
    public function doSomething(): void
    {
        // Read config 
        $value1 = $this->config['section']['key1'];
        
        // Output: my_value_1
        echo $value1;
    }
}

Hi Odan, Thanks, I’m going to implement it that way, thank you very much for the example.

Hi Odan, To call the MyExample class, you would do it as follows:
$config = new Config();
$valAccount = new doSomething($configall);
to pass the $config object to the construct of the MyExample class??

Hi Odan, I already managed to do it, thanks for your help, in the Config class, I added my email and other important configurations, and I can now use them through container injection.
With this I think we can conclude this point.

I am glad that I was able to help.

PS: Depending on your setup, mostly everything should created and injected automatically.
See here: PHP-DI - The Dependency Injection Container for humans