php-di / silex-bridge
PHP-DI在Silex中的集成
Requires
- php: >=5.5.9
- php-di/invoker: ~1.3
- php-di/php-di: ~5.0
- pimple/pimple: ~3.0
- silex/silex: ~2.0
Requires (Dev)
- phpunit/phpunit: ~4.5
- swiftmailer/swiftmailer: ^5.4
- twig/twig: ~1.8
This package is auto-updated.
Last update: 2024-09-19 21:44:34 UTC
README
安装
$ composer require php-di/silex-bridge
使用
为了从PHP-DI在Silex中的集成中受益,您只需使用DI\Bridge\Silex\Application
而不是原始的Silex\Application
。
以下是一个更新的经典Silex示例
<?php require_once __DIR__.'/../vendor/autoload.php'; $app = new DI\Bridge\Silex\Application(); $app->get('/hello/{name}', function ($name) use ($app) { return 'Hello '.$app->escape($name); }); $app->run();
优点
在Silex中使用PHP-DI允许您使用PHP-DI的所有优秀功能来绑定依赖项(使用定义文件、自动绑定、注解等)。
PHP-DI集成的另一个重大优点是能够在控制器、中间件和参数转换器内部使用依赖注入
class Mailer { // ... } $app->post('/register/{name}', function ($name, Mailer $mailer) { $mailer->sendMail($name, 'Welcome!'); return 'You have received a new email'; }); // You can also inject the whole request object like in a traditional Silex application $app->post('/register/{name}', function (Request $request, Mailer $mailer) { // ... }); // Injection works for middleware too $app->before(function (Request $request, Mailer $mailer) { // ... }); // And param converters $app->get('/users/{user}', function (User $user) { return new JsonResponse($user); })->convert('user', function ($user, UserManager $userManager) { return $userManager->findById($user); });
依赖注入使用类型提示
- 它可以与请求参数(如上面的示例中的
$name
)混合使用 - 参数的顺序不重要,它们通过类型提示(用于依赖注入)和名称(用于请求属性)来解决
- 它仅适用于可以类型提示的对象:例如,您不能注入字符串/整数值,并且您不能注入容器条目,其名称不是类/接口名称(例如
twig
或doctrine.entity_manager
)
将控制器作为服务
使用Silex和Pimple,您可以通过安装ServiceControllerServiceProvider
并使用特定语法来定义控制器作为服务。
使用PHP-DI桥接器,您可以原生地基于服务定义任何类型的可调用对象
- 对象方法
class HelloController { public function helloAction($name) { // ... } } $app->get('/{name}', [HelloController::class, 'helloAction']);
您会注意到上面我们给出的是类名而不是对象:只有当它被使用时,PHP-DI才会实例化该实例(并在其中注入依赖项)。
class HelloController { public function __invoke($name) { // ... } } $app->get('/{name}', HelloController::class);
同样,您会注意到我们传递的是类名而不是实例。PHP-DI会正确检测这是一个可调用的类并将其实例化。
中间件、路由变量转换器、错误处理程序和视图处理程序
上面描述的可调用对象解析(对于“将控制器作为服务”)也适用于注册其他Silex对象
例如,您可以定义如下中间件并让PHP-DI实例化它
class AuthMiddleware { public function beforeRoute(Request $request, Application $app) { // ... } } $app->before([AuthMiddleware::class, 'beforeRoute']);
配置容器
您可以通过创建自己的ContainerBuilder
并将其传递给应用程序来配置PHP-DI的容器
$containerBuilder = new DI\ContainerBuilder(); // E.g. setup a cache $containerBuilder->setDefinitionCache(new ApcCache()); // Add definitions $containerBuilder->addDefinitions([ // place your definitions here ]); // Register a definition file $containerBuilder->addDefinitions('config.php'); $app = new DI\Bridge\Silex\Application($containerBuilder);
Silex服务提供程序
Silex提供了几个“服务提供程序”,以预先配置一些第三方库,例如Twig或Doctrine。您仍然可以使用这些服务提供程序与此集成(尽管在更大的项目中,您可能想自己配置一切)。
以下是一个TwigServiceProvider的示例
$app->register(new Silex\Provider\TwigServiceProvider(), [ 'twig.path' => __DIR__ . '/views', ]); $app->get('/', function () use ($app) { return $app['twig']->render('home.twig'); });
由于使用自定义名称而不是实际类名(例如,使用twig
而不是Twig_Environment
类名)注册了Twig服务,因此您无法将这些依赖项注入到闭包中。如果要在控制器闭包中注入,则可以使用PHP-DI将条目别名化
$builder = new ContainerBuilder(); $builder->addDefinitions([ 'Twig_Environment' => \DI\get('twig'), // alias ]); // ... // Twig can now be injected in closures: $app->post('/', function (Twig_Environment $twig) { return $twig->render('home.twig'); });