matthiasnoback/symfony-service-definition-validator
Composer 安装命令:
composer require matthiasnoback/symfony-service-definition-validator
包简介
Library for validating service definitions created with the Symfony Dependency Injection Component
README 文档
README
By Matthias Noback
Installation
Using Composer:
php composer.phar require matthiasnoback/symfony-service-definition-validator
Problems the validator can spot
Using the service definition validator in this library, the following service definition problems can be recognized:
- Non-existing classes
- Non-existing factory methods
- Method calls to non-existing methods
- Missing required arguments for constructors
- Non-public constructor methods
- Non-static factory methods
- Missing required arguments for method calls
- Type-hint mismatches for constructor arguments (array or class/interface)
- Type-hint mismatches for method call arguments (array or class/interface)
- Syntax errors in arguments that are expressions
- Expressions that cause errors when being evaluated
This will prevent lots of run-time problems, and will warn you about inconsistencies in your service definitions early on.
Reporting false-negatives
I've tested the validator with the latest Symfony Standard Edition which has (of course) only valid service definitions.
Please let me know if the validator fails inside your project when it should not have failed. When you report an issue,
please attach a copy of the error message and the relevant lines in app/cache/dev/appDevDebugProjectContainer.xml.
Usage
If you have an existing Symfony application and you want to ensure that the service definitions are always valid the easiest way is to add the compiler pass to your bundle as described here. That will validate your service definitions every time the bundle is compiled, which happens every single request if the cache is turned off (the default in debug mode).
If you want to validate the service definitions in phpunit for a Symfony project follow the steps here.
Service validator factory
You can use the stand-alone validator for single definitions:
<?php use Matthias\SymfonyServiceDefinitionValidator\ServiceDefinitionValidatorFactory; // an instance of Symfony\Component\DependencyInjection\ContainerBuilder $containerBuilder = ...; $validatorFactory = new ServiceDefinitionValidatorFactory(); $validator = $validatorFactory->create($containerBuilder); // an instance of Symfony\Component\DependencyInjection\Definition $definition = ...; // will throw an exception for any validation error $validator->validate($definition);
To process multiple definitions at once, wrap the validator inside a batch validator:
<?php use Matthias\SymfonyServiceDefinitionValidator\BatchServiceDefinitionValidator; use Matthias\SymfonyServiceDefinitionValidator\Error\ValidationErrorFactory; $batchValidator = new BatchServiceDefinitionValidator( $validator, new ValidationErrorFactory() ); $errorList = $batchValidator->validate($serviceDefinitions);
The resulting error list will contain errors about problematic service definitions.
Compiler pass
To check for the validity of all your service definitions at compile time, add the ValidateServiceDefinitionsPass
compiler pass to the ContainerBuilder instance:
<?php use Matthias\SymfonyServiceDefinitionValidator\Compiler\ValidateServiceDefinitionsPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\PassConfig; class SomeBundle extends Bundle { public function build(ContainerBuilder $container) { if ($container->getParameter('kernel.debug')) { $container->addCompilerPass( new ValidateServiceDefinitionsPass(), PassConfig::TYPE_AFTER_REMOVING ); } } }
This compiler pass will throw an exception. The message of this exception will contain a list of invalid service definitions.
Running the validator in PHPUnit
In Symfony, adding the compiler pass will validate your services each time the page is loaded in your browser or when you use a command. But what if you want to run the validator on demand using PHPUnit? To do this, first set up the compiler pass as explained above and then create a new PHPUnit test with this inside:
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; class ContainerServiceDefinitionsTest extends WebTestCase { /** * @test */ public function validateServiceDefinitions() { $kernel = static::createKernel(); $kernel->boot(); // Add assertion to phpunit count which will prevent marking test as "risky" $this->addToAssertionCount(1); } }
This simple functional test just boots up the symfony kernel using the "test" environment. If you look back to the code you added to set up the compiler pass you'll see that we enabled the validator for the "test" environment too. So this simple PHPUnit test will validate the services each time it is run.
In fact, if you already have functional tests you don't need this test, since the kernel will be booted (and therefore the services will be validated) in the other functional tests. The example test above is only needed if you don't already have any Symfony functional tests of your application.
Configure the validator
Both ValidateServiceDefinitionsPass and ServiceDefinitionValidatorFactory accept a Configuration object.
It allows you to configure whether or not expression arguments should be evaluated. Since evaluating expressions can
cause all kinds of runtime errors, it is off by default, but you can easily turn it on:
<?php use Matthias\SymfonyServiceDefinitionValidator\Configuration; use Matthias\SymfonyServiceDefinitionValidator\Compiler\ValidateServiceDefinitionsPass; $configuration = new Configuration(); $configuration->setEvaluateExpressions(true); $compilerPass = new ValidateServiceDefinitionsPass($configuration); // or $validatorFactory = new ServiceDefinitionValidatorFactory($configuration);
Fixing invalid service definitions in third-party bundles
When the validator finds a problem with one of the service definitions that is your own, you can of course fix the problem yourself, but when the invalid service definition is defined in some other bundle, you can still fix problems by dynamically modifying the service definition. First you need to create a compiler pass:
<?php namespace YourBundle\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; class FixInvalidServiceDefinitionPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { // find the bad definition: $invalidDefinition = $container->findDefinition('the_service_id'); // for example, fix the class $invalidDefinition->setClass('TheRightClass'); } }
After you have selected the invalid service definition, you can modify it in any way you like. For a list of everything
you can do with Definition objects, see
http://symfony.com/doc/master/components/dependency_injection/definitions.html.
Don't forget to register the compiler pass in your bundle class:
<?php namespace MyBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; use Symfony\Component\DependencyInjection\ContainerBuilder; class MyBundle extends Bundle { public function build(ContainerBuilder $container) { if ($container->getParameter('kernel.debug')) { $container->addCompilerPass(new FixInvalidServiceDefinitionPass()); } } }
matthiasnoback/symfony-service-definition-validator 适用场景与选型建议
matthiasnoback/symfony-service-definition-validator 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 361.39k 次下载、GitHub Stars 达 89, 最近一次更新时间为 2013 年 07 月 30 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「dependency injection」 「Symfony2」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 matthiasnoback/symfony-service-definition-validator 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 matthiasnoback/symfony-service-definition-validator 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 matthiasnoback/symfony-service-definition-validator 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A fast and intuitive dependency injection container.
Symfony2 Barcode Generator Bundle with Twig function extension
Symfony bundle to connect AWS sns and sqs to create offline queue processing
Integrate the doctrine-translatable extension in Symfony2
Video Editor Bundle
Integrates php-amqplib with Symfony & RabbitMq. Formerly oldsound/rabbitmq-bundle.
统计信息
- 总下载量: 361.39k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 90
- 点击次数: 31
- 依赖项目数: 6
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2013-07-30