Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Invoker Laravel Package

php-di/invoker

Lightweight PHP library to call any callable with automatic dependency injection. Resolves function and method parameters by name and type-hints, integrates with PHP-DI, and supports default values for flexible invocations in frameworks, controllers, and CLI tools.

View on GitHub
Deep Wiki
Context7

Parameter resolvers

Extending the behavior of the Invoker is easy and is done by implementing a ParameterResolver:

interface ParameterResolver
{
    public function getParameters(
        ReflectionFunctionAbstract $reflection,
        array $providedParameters,
        array $resolvedParameters
    );
}
  • $providedParameters contains the parameters provided by the user when calling $invoker->call($callable, $parameters)
  • $resolvedParameters contains parameters that have already been resolved by other parameter resolvers

An Invoker can chain multiple parameter resolvers to mix behaviors, e.g. you can mix "named parameters" support with "dependency injection" support. This is why a ParameterResolver should skip parameters that are already resolved in $resolvedParameters.

Here is an implementation example for dumb dependency injection that creates a new instance of the classes type-hinted:

class MyParameterResolver implements ParameterResolver
{
    public function getParameters(
        ReflectionFunctionAbstract $reflection,
        array $providedParameters,
        array $resolvedParameters
    ) {
        foreach ($reflection->getParameters() as $index => $parameter) {
            if (array_key_exists($index, $resolvedParameters)) {
                // Skip already resolved parameters
                continue;
            }

            $class = $parameter->getClass();

            if ($class) {
                $resolvedParameters[$index] = $class->newInstance();
            }
        }

        return $resolvedParameters;
    }
}

To use it:

$invoker = new Invoker\Invoker(new MyParameterResolver);

$invoker->call(function (ArticleManager $articleManager) {
    $articleManager->publishArticle('Hello world', 'This is the article content.');
});

A new instance of ArticleManager will be created by our parameter resolver.

Chaining parameter resolvers

The fun starts to happen when we want to add support for many things:

  • named parameters
  • dependency injection for type-hinted parameters
  • ...

This is where we should use the ResolverChain. This resolver implements the Chain of responsibility design pattern.

For example the default chain is:

$parameterResolver = new ResolverChain([
    new NumericArrayResolver,
    new AssociativeArrayResolver,
    new DefaultValueResolver,
]);

It allows to support even the weirdest use cases like:

$parameters = [];

// First parameter will receive "Welcome"
$parameters[] = 'Welcome';

// Parameter named "content" will receive "Hello world!"
$parameters['content'] = 'Hello world!';

// $published is not defined so it will use its default value
$invoker->call(function ($title, $content, $published = true) {
    // ...
}, $parameters);

We can put our custom parameter resolver in the list and created a super-duper invoker that also supports basic dependency injection:

$parameterResolver = new ResolverChain([
    new MyParameterResolver, // Our resolver is at the top for highest priority
    new NumericArrayResolver,
    new AssociativeArrayResolver,
    new DefaultValueResolver,
]);

$invoker = new Invoker\Invoker($parameterResolver);
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport