2

i have some config file which return array of key-value

return [
    'my_key' => 'my value',
];

i have added it to the php-di container as definition

$builder->addDefinitions(dirname(__DIR__) . '/config.php');
$container = $builder->build();

question is how to access data from the config file inside some method of the class which is used inside di container ?

lets say i have some classes

class App
{
    private $router;

    public function __construct(Router $router, Request $request)
    {
        $this->router = $router;
        $this->router->doSmth();
    }
}

class Router
{
    public function doSmth()
    {
       // how to access here to the config.php data to receive 'my value'
    }
}

so when i call

$container->get('\Core\App');

everything starts but i have no idea how to access the definitions data inside the methods of the registered classes because i dont have container instance inside the container itself to call smth like

$container->get('my_key'); // return 'my value'
Eugene
  • 1,680
  • 3
  • 14
  • 23

3 Answers3

2

In your App class __constructor the parameters are injected. Just like those, you can inject the configuration there.

Your refer to the container by type hinting the ContainerInterface class. As mentioned in the issue on github your code for App will look like:

class App
{
    private $router;

    public function __construct(Router $router, Request $request, ContainerInterface $c)
    {
        $this->router = $router;
        $this->router->doSmth($c->get('my_key'));
    }
}

class Router
{
    public function doSmth($my_key)
    {
       // You now have access to that particular key from the settings
    }
}

This will make your Router dependent on getting the config by the doSmth() function.


Depending on your usage of the Router class, you might want to loose that dependency on calling doSmth($my_key) with that config parameter. Since in the App class you are injecting the Router class, it means you can also profit from injection in the Router class itself. Just like how you __construct your App class, you can also do that with your Router class.

Doing this from the top of my head now, but this should work if I am not mistaken...

Your code will look like this:

class App
{
    private $router;

    public function __construct(Router $router, Request $request)
    {
        $this->router = $router;
        $this->router->doSmth();
    }
}

class Router
{
    private $some_setting;

    public function __construct(ContainerInterface $c)
    {
       $this->some_setting = $c->get('my_key');
    }

    public function doSmth()
    {
       // You now have access to $this->some_setting
    }
}

Note that the my_key key comes directly from the PHP-DI container definitions if for example a settings.php file with an array is added as definitions. More about definitions here. As I am combining this myself with the Slim framework, I usually prepend my keys in settings.php with settings. like for example setting.my_key. However there are probably cleaner solutions available if making use of the ability to extends definitions.

Mikroware
  • 344
  • 2
  • 9
  • TY for your fast answer. yesterday i kept trying and found this magic. it was just enough to add in constructor signature reference to the **Psr\Container\ContainerInterface** just like you show here in the answer and magic appears :) have another question you address in your example to **'settings.my_key'**. it is possible to make definitions "named" ? or this is just good practice to name array keys in this way (dot separated) for DI container ? – Eugene Jun 04 '19 at 10:24
  • Not sure what you mean with "named" definitions. Settings are somehow converted to the dot key notation when added as array definition. For me this was good enough, so I stopped bothering researching other solutions ;) – Mikroware Jun 04 '19 at 10:43
  • strange, it doesnt work on my side. if im trying by filename **No entry or class found for 'routes.hello'**, with just settings doesn't work as well **No entry or class found for 'settings.hello'**, only when i call just "hello" **$c->get('hello')** it does work. Only if i name array key as **settings.hello** then i can access it as "settings.hello" – Eugene Jun 04 '19 at 11:18
  • 2
    @Eugene Ah, I am terrible sorry! Totally forgot about that part. My key in my `settings.php` array is indeed `settings.my_key`. With that I followed how PHP-DI documented the configuration of Slim (http://php-di.org/doc/frameworks/slim.html#configuring-slim). I also did not want to pollute the container root keys with setting keys (unless clearly a setting, thus `settings.` prepended. Now that I read more about definitions, you could probably created a cleaner way for your setting definitions (maybe using this http://php-di.org/doc/definition-overriding.html#arrays) – Mikroware Jun 04 '19 at 13:29
  • I edited my answer to make the part about where the key comes from a bit more clear. – Mikroware Jun 04 '19 at 13:38
0

You need to configure what to inject in your objects: http://php-di.org/doc/php-definitions.html#autowired-objects

Matthieu Napoli
  • 48,448
  • 45
  • 173
  • 261
-1

If you just want the value, I think you can just use DI\get.

public function doSmth() {
    echo DI\get('my_key');
}

From here: http://php-di.org/doc/environments.html

serialworm
  • 761
  • 3
  • 13