有没有办法在 symfony2 中自动更新 AppKernel?

2022-01-21 00:00:00 console php symfony composer-php bundle

可能类似于 generate:bundle 命令(在生成捆绑包后提示更新 AppKernel)或 Composer(使用您安装的依赖项更新您的自动加载).

Maybe something similar to the generate:bundle command (which after generating the bundle prompts to update the AppKernel) or to Composer (which updates your autoload with the dependencies you install).

我想获得与 generate:bundle 类似的功能,但我不想创建一个新的包,而是想添加一个刚刚下载的包,而无需手动编辑 AppKernel.

I want to get a similar functionality to the generate:bundle, but instead of creating a new bundle I want to add a bundle I just downloaded without having to edit the AppKernel manually.

推荐答案

我找不到 EXTEND 现有命令的方法,所以我想在现有包中创建一个新的控制台命令.

I couldn't find a way to EXTEND an existing command, so my thought goes to create a new console command into an existing bundle.

namespace YourOriginalBundleCommand;

use SymfonyBundleFrameworkBundleCommandContainerAwareCommand;
use SymfonyComponentConsoleInputArrayInput;
use SymfonyComponentConsoleInputInputArgument;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleInputInputOption;
use SymfonyComponentConsoleOutputOutputInterface;

class AppendNewBundleCommand extends ContainerAwareCommand
{
    protected $appKernel;

    protected function configure()
    {
        $this
            ->setName('yourbundle:appendnewbundle')
            ->setDescription('Append a new bundle to the AppKernel.php')
            ->addArgument('namespace', InputArgument::REQUIRED, 'Define your new bundle/namespace')
        ;
        $this->appKernel = __DIR__.'/../../../../app/AppKernel.php';
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        if (!file_exists($this->appKernel)) {
            throw new ErrorException(sprintf("Could not locate file %s",$this->appKernel));
        }
        if (!is_writable($this->appKernel)) {
            throw new ErrorException(sprintf('Cannot write into AppKernel (%s)',$this->appKernel));
        }

        $namespace = $input->getArgument('namespace');
        $appContent = file_get_contents($this->appKernel);

        $bundle = str_replace("/","\",$namespace)."\".str_replace("/","",$namespace);
        $newBundle = "new {$bundle}(),";

        $pattern = '/$bundless?=s?array((.*?));/is';
        preg_match($pattern, $appContent,$matches);

        $bList = rtrim($matches[1],"
 ");
        $e = explode(",",$bList);
        $firstBundle = array_shift($e);
        $tabs = substr_count($firstBundle,'    ');

        $newBList = "$bundles = array("
                            .$bList."
"
                            .str_repeat('    ', $tabs).$newBundle."
"
                        .str_repeat('    ',$tabs-1).");";

        file_put_contents($this->appKernel,preg_replace($pattern,$newBList,$appContent));
    }
}

您现在可以在生成捆绑包后立即执行它

You can now execute it, right after generating your bundle by doing

php app/console yourbundle:appendnewbundle Your/SecondBundle

这会将其附加到现有捆绑包列表中

This will append this to the list of existing bundles

new YourSecondBundleYourSecondBundle(),

如果你有一个标准的 (symfony2) AppKernel,这可以工作.例如:

This works if you have a standard (symfony2) AppKernel. Ex:

<?php

use SymfonyComponentHttpKernelKernel;
use SymfonyComponentConfigLoaderLoaderInterface;

class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            new SymfonyBundleFrameworkBundleFrameworkBundle(),
            new SymfonyBundleSecurityBundleSecurityBundle(),
            new SymfonyBundleTwigBundleTwigBundle(),
            new SymfonyBundleMonologBundleMonologBundle(),
            new SymfonyBundleSwiftmailerBundleSwiftmailerBundle(),
            new SymfonyBundleDoctrineBundleDoctrineBundle(),
            new SymfonyBundleAsseticBundleAsseticBundle(),
            new SensioBundleFrameworkExtraBundleSensioFrameworkExtraBundle(),
            new JMSSecurityExtraBundleJMSSecurityExtraBundle(),
            new OrnicarApcBundleOrnicarApcBundle(),
            new YourOriginalBundleYourOriginalBundle(),
        );

        if (in_array($this->getEnvironment(), array('dev', 'test'))) {
            $bundles[] = new SymfonyBundleWebProfilerBundleWebProfilerBundle();
            $bundles[] = new SensioBundleDistributionBundleSensioDistributionBundle();
            $bundles[] = new SensioBundleGeneratorBundleSensioGeneratorBundle();
        }

        return $bundles;
    }

    public function registerContainerConfiguration(LoaderInterface $loader)
    {
        $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
    }
}

相关文章