Deconstructing Symfony: Part I – Getting Rid of Bad Practices Takes Effort

I tried to avoid the bad practice of generating code. So I decided it was enough and created a custom Application.php class on my app/ folder and use that instead inside the console script. Something like this:

#!/usr/bin/env php
<?php
 
set_time_limit(0);
 
require_once __DIR__.'/bootstrap.php.cache';
require_once __DIR__.'/AppKernel.php';
require_once __DIR__.'/Application.php';
 
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Debug\Debug;
 
$input = new ArgvInput();
$env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod';
 
if ($debug) {
    Debug::enable();
}
 
$kernel = new AppKernel($env, $debug);
$application = new Application($kernel);
$application->run($input);

The Application.php class basically extends the regular application but overrides this method:

<?php
 
use Symfony\Bundle\FrameworkBundle\Console\Application as BaseApplication;
 
class Application extends BaseApplication
{
    protected function registerCommands()
    {
        $container = $this->getKernel()->getContainer();
 
        if ($container->hasParameter('console.command.ids')) {
            foreach ($container->getParameter('console.command.ids') as $id) {
                $this->add($container->get($id));
            }
        }
 
        $this->addCommands($this->getKernel()->getCommands());
    }
}

The only extra step is to basically register by hand the Commands that you actually:

– care about
– are good commands for your project
– are actually used often
– are safe for your developers
– are within your flow
– are good practices

So the method looks like this:

    public function getCommands()
    {
        $containerAwares = [
            new CacheClearCommand(),
            new DumpCommand(),
            new AssetsInstallCommand(),
            new CacheWarmupCommand(),
            new ConfigDumpReferenceCommand(),
            new ContainerDebugCommand(),
            new RouterDebugCommand(),
            new RouterMatchCommand(),
            new ServerRunCommand(),
            new LintCommand(),
            new CreateDatabaseDoctrineCommand(),
            new DropDatabaseDoctrineCommand(),
            new InfoDoctrineODMCommand(),
            new LoadDataFixturesDoctrineODMCommand(),
            new DebugCommand(),
            new SendEmailCommand(),
        ];
 
        $regularCommands = [
            new UpdateSchemaDoctrineCommand(),
            new UpdateSchemaDoctrineODMCommand(),
            new ClearMetadataCacheDoctrineCommand(),
            new ClearMetadataCacheDoctrineODMCommand(),
            new ClearQueryCacheDoctrineCommand(),
            new ClearResultCacheDoctrineCommand(),
            new EnsureProductionSettingsCommand(),
            new QueryDoctrineODMCommand(),
            new CreateSchemaDoctrineODMCommand(),
            new DropSchemaDoctrineODMCommand(),
            new TailCursorDoctrineODMCommand(),
            new RunDqlDoctrineCommand(),
            new RunSqlDoctrineCommand(),
            new CreateSchemaDoctrineCommand(),
            new DropSchemaDoctrineCommand(),
            new UpdateSchemaDoctrineCommand(),
            new ValidateSchemaCommand(),
        ];
 
        foreach ($containerAwares as $command) {
            $command->setContainer($this->getContainer());
        }
 
        return array_merge($containerAwares, $regularCommands);
    }

You can let go of the commands that are mongodb if you don’t use mongodb. This actually feels faster and I don’t have to worry about generators.

That is it, let the reader understand 🙂

Encouragements in all good.

@cordoval