4

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.

Yuri Makassiouk
  • 425
  • 3
  • 16
  • 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 Sep 22 '14 at 13:56

4 Answers4

3

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.

Yuri Makassiouk
  • 425
  • 3
  • 16
  • 4
    Hi, author of PHP-DI here. Here is an example of how to use it with the Symfony Console component (outside of Symfony framework): https://github.com/mnapoli/IsItMaintained/blob/master/bin/console If you have any question ask it on StackOverflow with the `php-di` tag or head in the chat: https://gitter.im/mnapoli/PHP-DI – Matthieu Napoli Sep 24 '14 at 03:04
  • Thank you for the link. Well, I ended up doing something similar, except that I started out (even before integrating DI) by having some commands created as default ones in the application class. So, to continue along that path, I had to inject the container into the application class and pull the command instances there. Which is OK for the time being. – Yuri Makassiouk Sep 24 '14 at 21:46
1

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');
COil
  • 7,201
  • 2
  • 50
  • 98
  • Thank you for the answer. How is the application object constructed for the above snippet to be valid? When I tried what you are suggesting, I got an error that I mentioned in my question (Application::getKernel() method not found). Which makes sense, because the application I was constructing was an instance of Symfony\Component\Console\Application which does not have a kernel – Yuri Makassiouk Sep 21 '14 at 19:24
  • 1
    Your are not using the full stack framework? So it is normal, you will need to build the container yourself and inject it into the command. – COil Sep 21 '14 at 19:30
  • 1
    No, I'm not! The application is not big enough to bring heavy guns in. That's kind of what the question was about. For some reason the documentation is very vague about this. So, Symfony\Component\Console\Application equals no container other than we create for ourselves. – Yuri Makassiouk Sep 21 '14 at 20:55
  • 1
    Check out this blog post: http://dcousineau.com/blog/2013/03/28/using-symfony-console-from-scratch/ – COil Sep 22 '14 at 10:18
0

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);
Guillaume PETIT
  • 73
  • 1
  • 2
  • 5
0

You could use a solution I just pushed it to packagist.org. Includes full working symfony/dependency-injection. You're welcome to give it a shot. use composer to create your own project composer create-project coral-media/crune project_dir or just clone the repository. https://packagist.org/packages/coral-media/crune You only need to install DBAL dependencies (I don't suggest ORM if you don't really need it). Configure connection parameters in .env and just define a service to handle connection. That service can be injected in your Commands using public setMyService($myService) method with @required annotation. Also you could create a Connection class and bind is as parameter in your command constructor.The crune boilerplate also supports autowire and autoconfiguring features.

rernesto
  • 554
  • 4
  • 11