mmoreram / symfony-bundle-dependencies
Symfony Bundles 的依赖解析器
Requires
- php: ^7.1|^8.0
- symfony/http-kernel: ^3.2|^4.0|^5.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.0
- mmoreram/php-formatter: ^1.3.1
- phpspec/prophecy-phpunit: ^2
- phpunit/phpunit: ^9
- symfony/dependency-injection: ^3.2|^4.0|^5.0
README
此包的最低要求是 PHP 7.1 和 Symfony 3.2,因为该包使用了这两个版本的特性。如果您尚未使用它们,我鼓励您这么做。
此包提供了一种非常简单的方式来添加 Symfony Bundles 之间的依赖关系。Composer 在一个非常轻量级的层中定义这些定义,只下载这些依赖包。包也应该强制其他包在应用中实例化,以符合依赖注入的依赖关系。
对于您的包
如果您希望您的包提供此功能,那么只需让您的包实现一个接口即可。就这么简单。
请注意,此添加只会提供与使用此项目的项目兼容性,而不会以任何方式影响不使用它的项目。
use Symfony\Component\HttpKernel\Bundle\Bundle; use Mmoreram\SymfonyBundleDependencies\DependentBundleInterface; /** * My Bundle */ class MyBundle extends Bundle implements DependentBundleInterface { /** * Create instance of current bundle, and return dependent bundle namespaces * * @return array Bundle instances */ public static function getBundleDependencies(KernelInterface $kernel) { return [ 'Another\Bundle\AnotherBundle', 'My\Great\Bundle\MyGreatBundle', // ... ]; } }
也许您的包依赖项需要构造函数中的特定值。嗯,这是一个非常非常奇怪的情况,您应该绝对避免它,但您可以通过添加实例而不是命名空间来做到这一点。
use Symfony\Component\HttpKernel\Bundle\Bundle; use Mmoreram\SymfonyBundleDependencies\DependentBundleInterface; /** * My Bundle */ class MyBundle extends Bundle implements DependentBundleInterface { /** * Create instance of current bundle, and return dependent bundle namespaces * * @return array Bundle instances */ public static function getBundleDependencies(KernelInterface $kernel) { return [ 'Another\Bundle\AnotherBundle', 'My\Great\Bundle\MyGreatBundle', new \Even\Another\Bundle\EvenAnotherBundle('some-value'), ]; } }
默认情况下,所有定义为命名空间的包都使用内核对象作为第一个参数进行实例化,所以这样做根本没有任何意义。
use Mmoreram\SymfonyBundleDependencies\DependentBundleInterface; /** * My Bundle */ class MyBundle implements DependentBundleInterface { /** * Create instance of current bundle, and return dependent bundle namespaces * * @return array Bundle instances */ public static function getBundleDependencies(KernelInterface $kernel) { return [ new \Even\Another\Bundle\EvenAnotherBundle($this), ]; } }
正如您稍后将要看到的,使用实例而不是名称将消除在最终项目中使用缓存的可能性。
对于您的内核
在您的项目中,您应该能够解决所有这些依赖关系。这就是为什么此包还为您提供了在内核中执行此操作的方法。
use Symfony\Component\HttpKernel\Kernel; use Mmoreram\SymfonyBundleDependencies\BundleDependenciesResolver; /** * Class AppKernel */ class AppKernel extends Kernel { use BundleDependenciesResolver; /** * Register application bundles * * @return array Array of bundles instances */ public function registerBundles() { return $this->getBundleInstances([ '\My\Bundle\MyBundle', ]); } }
在这种情况下,您也可以传递包的实例而不是字符串。
use Symfony\Component\HttpKernel\Kernel; use Mmoreram\SymfonyBundleDependencies\BundleDependenciesResolver; /** * Class AppKernel */ class AppKernel extends Kernel { use BundleDependenciesResolver; /** * Register application bundles * * @return array Array of bundles instances */ public function registerBundles() { return $this->getBundleInstances([ new \My\Bundle\MyBundle($this), ]); } }
性能
正如您可能看到的,解析依赖关系可能会严重损害您的网站性能。每次内核启动时,都会重新解析所有依赖关系,这完全没有意义。
此包还为您提供了一个缓存层,将第二次内核启动后的缓存降至0,直到您的下一次部署(缓存文件存储在内核缓存文件夹中)。
只需对您的代码进行一个简单的更改。就这么简单。
use Mmoreram\SymfonyBundleDependencies\CachedBundleDependenciesResolver; /** * Class AppKernel */ class AppKernel { use CachedBundleDependenciesResolver; /** * Register application bundles * * @return array Array of bundles instances */ public function registerBundles() { return $this->getBundleInstances([ '\My\Bundle\MyBundle', ]); } }
仅当所有依赖关系都定义为字符串而不是实例时,才能使用缓存来缓存包依赖关系解析。
此库假定,一旦您的项目中任何可能改变依赖关系文件的东西发生变化,您将删除缓存。请记住这一点。
顺序
当然,顺序很重要。如果您的两个依赖关系以不同的参数实例化相同的包,则首先定义的那个将是赢家。在这种情况下,如果您想明确定义即使其他依赖关系也是如此的包的实例化方式,请在您的数组中将此包放在开头。
use Symfony\Component\HttpKernel\Kernel; use Mmoreram\SymfonyBundleDependencies\BundleDependenciesResolver; /** * Class AppKernel */ class AppKernel extends Kernel { use BundleDependenciesResolver; /** * Register application bundles * * @return array Array of bundles instances */ public function registerBundles() { return $this->getBundleInstances([ new \My\Bundle\MyBundle($this, true), 'Another\Bundle\AnotherBundle', 'My\Great\Bundle\MyGreatBundle', ]); } }
这也适用于定义包依赖关系。