4
votes

A Symfony novice here. After reading some of the Symfony documentation and some answers here at SO, I am now almost completely confused. I am trying to use the console application component and create a small db-aware console application.

Many people state that in order to use Symfony's DI features it would be enough to inherit my command class not from Symfony\Component\Console\Command\Command but from ContainerAwareCommand. However when I try this I get a Method Not Found error on an application::getKernel() call.

I have a feeling that DI features are in fact not available in a console application based on the console component. Is there another kind of Symfony console application, for example, based on the full-blown framework?

I very much like the simple framework provided by the console component Symfony\Component\Console\Application. But the question is then - what to do for dependency injection and DBAL? All examples that I find seem to refer to the full Symfony framework and get me just all the more stuck.

3
Given that you are new to S2 I would suggest going with the full framework just to get started. Get you app running and get a bit of experience on using the components. Then you can try to strip stuff out. Especially if you want access to Doctrine 2 DBAL. The config for it is a bit of a pain. - Cerad

3 Answers

3
votes

Just a quick update on my progress if anybody stumbles upon the same problems.

  1. I incorporated into my project the PHP-DI dependency injection framework, which seems to be working fairly well with no configuration (so far) - it figures out quite a lot by reflection, actually.
  2. The same way, Doctrine\DBAL is included as a standalone library (I opted against the O/RM part of it, as it is really a tiny project and I'm on a much firmer ground with SQL than anything else) and the connection is simply returned by a connection provider which is injected wherever needed by the DI.

One thing I couldn't figure out is how to have the command classes instantiated by the DI library without my help, so I actually had to inject the container itself into my overridden application class and override the getDefaultCommands() where I then pull the instances out of the container manually. Not ideal but will have to do for now.

1
votes

If your command extends ContainerAwareCommand

...
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
...

class MyCommand extends ContainerAwareCommand
{

The DI container is available with the getContainer() method. (like in a standard controller), ex:

$this->validator = $this->getContainer()->get('validator');
0
votes

I don't know if your question is still relevant, but I have an answer as I stumbled across the same problem here.

You just have to create the kernel yourself and give it to the \Symfony\Bundle\FrameworkBundle\Console\Application that extends the basic \Symfony\Component\Console\Application.

<?php
// CronRun.php

require __DIR__.'/../../../../vendor/autoload.php';
require_once __DIR__.'/../../../../app/AppKernel.php';

$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();

$application = new \Symfony\Bundle\FrameworkBundle\Console\Application($kernel);
$application->add(new \KingdomHall\TaskBundle\Command\CronCommand());
$input = new \Symfony\Component\Console\Input\StringInput('k:c:r');
$application->run($input);