5.2. Silex
这是一篇协同翻译的文章,你可以点击『我来翻译』按钮来参与翻译。
PHP-DI in Silex#
Installation#
$ composer require php-di/silex-bridge
Usage#
In order to benefit from PHP-DI's integration in Silex, you only need to use DI\Bridge\Silex\Application
instead of the original Silex\Application
.
Here is the classic Silex example updated:
<?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();
Benefits#
Using PHP-DI in Silex allows you to use all the awesome features of PHP-DI to wire your dependencies (using the definition files, autowiring, annotations, …).
Another big benefit of the PHP-DI integration is the ability to use dependency injection inside controllers, middlewares and param converters:
class Mailer
{
// ...
}
$app->post('/register/{name}', function ($name, Mailer $mailer) {
$mailer->sendMail($name, 'Welcome!');
return 'You have received a new email';
});
// 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);
});
Dependency injection works using type-hinting:
- it can be mixed with request parameters (
$name
in the example above) - the order of parameters doesn't matter, they are resolved by type-hint (for dependency injection) and by name (for request parameters)
- it only works with objects that you can type-hint: you can't inject string/int values for example, and you can't inject container entries whose name is not a class/interface name (e.g.
twig
ordoctrine.entity_manager
)
Controllers as services#
With Silex and Pimple, you can define controllers as services by installing the ServiceControllerServiceProvider
and using a specific notation.
With the PHP-DI bridge, you can natively define any type of callable based on services:
- object method:
class HelloController
{
public function helloAction($name)
{
// ...
}
}
$app->get('/{name}', [HelloController::class, 'helloAction']);
You will notice above that we give the class name and not an object: PHP-DI will instantiate the instance (and inject dependencies inside it) only if it is used.
class HelloController
{
public function __invoke($name)
{
// ...
}
}
$app->get('/{name}', HelloController::class);
Again you will notice that we pass the class name and not an instance. PHP-DI will correctly detect that this is an invokable class and will instantiate it.
Middlewares, route variable converters, error handlers and view handlers#
The callable resolution described above (for "controllers as services") applies for registering other Silex objects:
For example you can define a middleware like so and let PHP-DI instantiate it:
class AuthMiddleware
{
public function beforeRoute(Request $request, Application $app)
{
// ...
}
}
$app->before([AuthMiddleware::class, 'beforeRoute']);
Configuring the container#
You can configure PHP-DI's container by creating your own ContainerBuilder
and passing it to the application:
$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。 你仍然可以通过这种集成使用这些服务提供者(在较大的项目中你可能希望自己配置所有内容)。
下面是 Twig 服务提供者 的例子:
$app->register(new Silex\Provider\TwigServiceProvider(), [
'twig.path' => __DIR__ . '/views',
]);
$app->get('/', function () use ($app) {
return $app['twig']->render('home.twig');
});
由于 Twig 服务是使用自定义名称而不是实际类名注册的(例如,用 twig
代替 Twig_Environment
类名),你不能将此类依赖项注入到闭包中。 如果你想注入控制器闭包,你可以使用 PHP-DI 别名条目:
$builder = new ContainerBuilder();
$builder->addDefinitions([
'Twig_Environment' => \DI\get('twig'), // 别名
]);
// ...
// Twig 现在可以注入到闭包:
$app->post('/', function (Twig_Environment $twig) {
return $twig->render('home.twig');
});
更多#
在 GitHub 上阅读有关 Silex-Bridge 项目 的更多信息。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。