2

The issue

I have an unexpected warning from PHPStorm when I try to set a new value in a PHP-DI container.

Given the following code:

function inject(Psr\Container\ContainerInterface $container){
    $container->set(RandomClass::class, new RandomClass());
}

$container = new DI\Container(); class is instantiated

inject($container);

The following warning is triggered

Potentially polymorphic call. does not have members in its hierarchy

I understand what the warning means, but I do not see why it pops up, especially since I have not found any occurrences of this situation while looking on Google and SO and the documentation does not mention it.

Is there something I am missing, or is this a "false positive" ?

Noah Boegli
  • 750
  • 1
  • 7
  • 24
  • Hey, PHP-DI author here. That is very weird indeed, the method really exists on the `Container` class, I don't really know what's happening. – Matthieu Napoli Aug 25 '20 at 09:22
  • Hi @MatthieuNapoli! I think I have figured it out. See the updated code snipped in my question. It comes from the fact that `Psr\Container\ContainerInterface` does not contain the definition for `set` (only `get` and `has`) which is a bit confusing. Replacing `Psr\Container\ContainerInterface` by `DI\Container` fixes the warning. However it breaks the idea of having a standard interface... – Noah Boegli Aug 25 '20 at 09:45
  • Oh ok, you changed the code example in the question, now it makes more sense. – Matthieu Napoli Aug 26 '20 at 11:44

2 Answers2

1

The set() method is not part of Psr\Container\ContainerInterface.

If you want to use that method, you can't typehint against the interface because your code explicitly needs a PHP-DI instance.

Your code doesn't have to be generic, don't overthink things too much. The PSR is useful mostly for frameworks and libraries (who need to be compatible with multiple containers), not for end-users.

The day you switch container library you will have many more complex things to do than just replacing the set() call.

Matthieu Napoli
  • 48,448
  • 45
  • 173
  • 261
0

The reason behind the issue

Given the following code (which is very similar to the one I use)

function inject(Psr\Container\ContainerInterface $container){
    $container->set(RandomClass::class, new RandomClass());
}

$container = new DI\Container(); class is instantiated

inject($container);

The $container->set(...) call is going to trigger the following warning

Potentially polymorphic call. does not have members in its hierarchy

This is to be expected as Psr\Container\ContainerInterface only contains definitions for the following methods

  • get($id)
  • has($id)

The solution

Two possible solutions for this issue:

  • Type the methods directly with the container, making sure to not use the FQN of the class but only use Container and "use the namespace", it will make changing to a new container package easier (because this is still the goal behind PSRs, being able to almost hot-swap packages).
  • Create a custom interface based on Psr\Container\ContainerInterface and add the required methods to it.

Or, eventually, you can try to make PHP-FIG extend the PSR-11 standard to include a standard set($id, $value) method.

Noah Boegli
  • 750
  • 1
  • 7
  • 24