php-di/invoker
Composer 安装命令:
composer require php-di/invoker
包简介
Generic and extensible callable invoker
README 文档
README
Generic and extensible callable invoker.
Why?
Who doesn't need an over-engineered call_user_func()?
Named parameters
Does this Silex example look familiar:
$app->get('/project/{project}/issue/{issue}', function ($project, $issue) { // ... });
Or this command defined with Silly:
$app->command('greet [name] [--yell]', function ($name, $yell) { // ... });
Same pattern in Slim:
$app->get('/hello/:name', function ($name) { // ... });
You get the point. These frameworks invoke the controller/command/handler using something akin to named parameters: whatever the order of the parameters, they are matched by their name.
This library allows to invoke callables with named parameters in a generic and extensible way.
Dependency injection
Anyone familiar with AngularJS is familiar with how dependency injection is performed:
angular.controller('MyController', ['dep1', 'dep2', function(dep1, dep2) { // ... }]);
In PHP we find this pattern again in some frameworks and DI containers with partial to full support. For example in Silex you can type-hint the application to get it injected, but it only works with Silex\Application:
$app->get('/hello/{name}', function (Silex\Application $app, $name) { // ... });
In Silly, it only works with OutputInterface to inject the application output:
$app->command('greet [name]', function ($name, OutputInterface $output) { // ... });
PHP-DI provides a way to invoke a callable and resolve all dependencies from the container using type-hints:
$container->call(function (Logger $logger, EntityManager $em) { // ... });
This library provides clear extension points to let frameworks implement any kind of dependency injection support they want.
TL/DR
In short, this library is meant to be a base building block for calling a function with named parameters and/or dependency injection.
Installation
$ composer require PHP-DI/invoker
Usage
Default behavior
By default the Invoker can call using named parameters:
$invoker = new Invoker\Invoker; $invoker->call(function () { echo 'Hello world!'; }); // Simple parameter array $invoker->call(function ($name) { echo 'Hello ' . $name; }, ['John']); // Named parameters $invoker->call(function ($name) { echo 'Hello ' . $name; }, [ 'name' => 'John' ]); // Use the default value $invoker->call(function ($name = 'world') { echo 'Hello ' . $name; }); // Invoke any PHP callable $invoker->call(['MyClass', 'myStaticMethod']); // Using Class::method syntax $invoker->call('MyClass::myStaticMethod');
Dependency injection in parameters is supported but needs to be configured with your container. Read on or jump to Built-in support for dependency injection if you are impatient.
Additionally, callables can also be resolved from your container. Read on or jump to Resolving callables from a container if you are impatient.
Parameter resolvers
Extending the behavior of the Invoker is easy and is done by implementing a ParameterResolver.
This is explained in details the Parameter resolvers documentation.
Built-in support for dependency injection
Rather than have you re-implement support for dependency injection with different containers every time, this package ships with 2 optional resolvers:
-
This resolver will inject container entries by searching for the class name using the type-hint:
$invoker->call(function (Psr\Logger\LoggerInterface $logger) { // ... });
In this example it will
->get('Psr\Logger\LoggerInterface')from the container and inject it.This resolver is only useful if you store objects in your container using the class (or interface) name. Silex or Symfony for example store services under a custom name (e.g.
twig,db, etc.) instead of the class name: in that case use the resolver shown below. -
ParameterNameContainerResolverThis resolver will inject container entries by searching for the name of the parameter:
$invoker->call(function ($twig) { // ... });
In this example it will
->get('twig')from the container and inject it.
These resolvers can work with any dependency injection container compliant with PSR-11.
Setting up those resolvers is simple:
// $container must be an instance of Psr\Container\ContainerInterface $container = ... $containerResolver = new TypeHintContainerResolver($container); // or $containerResolver = new ParameterNameContainerResolver($container); $invoker = new Invoker\Invoker; // Register it before all the other parameter resolvers $invoker->getParameterResolver()->prependResolver($containerResolver);
You can also register both resolvers at the same time if you wish by prepending both. Implementing support for more tricky things is easy and up to you!
Resolving callables from a container
The Invoker can be wired to your DI container to resolve the callables.
For example with an invokable class:
class MyHandler { public function __invoke() { // ... } } // By default this doesn't work: an instance of the class should be provided $invoker->call('MyHandler'); // If we set up the container to use $invoker = new Invoker\Invoker(null, $container); // Now 'MyHandler' is resolved using the container! $invoker->call('MyHandler');
The same works for a class method:
class WelcomeController { public function home() { // ... } } // By default this doesn't work: home() is not a static method $invoker->call(['WelcomeController', 'home']); // If we set up the container to use $invoker = new Invoker\Invoker(null, $container); // Now 'WelcomeController' is resolved using the container! $invoker->call(['WelcomeController', 'home']); // Alternatively we can use the Class::method syntax $invoker->call('WelcomeController::home');
That feature can be used as the base building block for a framework's dispatcher.
Again, any PSR-11 compliant container can be provided.
php-di/invoker 适用场景与选型建议
php-di/invoker 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 64.42M 次下载、GitHub Stars 达 268, 最近一次更新时间为 2015 年 04 月 24 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「dependency」 「invoke」 「injection」 「dependency-injection」 「callable」 「invoker」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 php-di/invoker 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 php-di/invoker 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 php-di/invoker 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Utility classes for analyse code and invoking callables with verification of arguments and type casting
A fast and intuitive dependency injection container.
Swoole synchronous blocking code invoke library
free as in freedom php component to easy up usage (reading and writing) of csv files for php 5.6 and above
Dependency injection container for the Monolith framework.
Http Microframework for Hack
统计信息
- 总下载量: 64.42M
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 272
- 点击次数: 29
- 依赖项目数: 83
- 推荐数: 2
其他信息
- 授权协议: MIT
- 更新时间: 2015-04-24