I'm trying to getDoctrine() outside of the controller.
I've created this service:
config/services.yml
services:
update_command:
class: project\projBundle\Command\Update
arguments: ['@doctrine.orm.entity_manager']
and in my app/config/config.yml
imports:
- { resource: "@projectprojBundle/Resources/config/services.yml" }
so and the class that I want to use:
namespace project\projBundle\Command;
use Doctrine\ORM\EntityManager;
class Update {
protected $em;
public function __construct(EntityManager $em) {
$this->em = $em;
}
but every time I want to do this: (I'm doing this right?)
$up = new Update();
i got this error:
Catchable Fatal Error: Argument 1 passed to ...\Update::__construct() must be an instance of Doctrine\ORM\EntityManager, none given, called in .../Update.php line 7
Simple solution
If you're implementing a Symfony command (that can be executed in a cron tab), you can access the service container from the command.
<?php
namespace MyProject\MyBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UpdateCommand extends ContainerAwareCommand
{
protected $em;
protected function configure()
{
$this->setName('myproject:mybundle:update') ;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->em = $this->getContainer()->get('doctrine.orm.entity_manager');
}
}
That way, you get the entity manager from a command and don't need to declare this class as a service. You can therefore remove the configuration you added in the services.yml
file.
An other solution (cleaner)
This solution allows better separation of concerns and can therefore be easily unit tested and reused in other parts of your Symfony application (not only as a command).
Move all the logic part of your "update" command to a dedicated class that you will declare as a service:
<?php
namespace MyProject\MyBundle\Service;
use Doctrine\ORM\EntityManager;
class MyUpdater
{
protected $em;
public function __construct($em)
{
$this->em = $em;
}
public function runUpdate()
{
// All your logic code here
}
}
Declare it as a service in your services.yml
file:
services:
myproject.mybundle.myupdater:
class: MyProject\MyBundle\Service\MyUpdater
arguments: ['@doctrine.orm.entity_manager']
Simply call your service from your command :
<?php
namespace MyProject\MyBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class UpdateCommand extends ContainerAwareCommand
{
protected function configure()
{
$this->setName('myproject:mybundle:update') ;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$myUpdater = $this->getContainer()->get('myproject.mybundle.myupdater');
$myUpdater->runUpdate();
}
}
You have to either inject your newly created @update_command
service or get it from the container in order to have the @doctrine.orm.entity_manager
service injected automatically.
You're just creating the object with no argument, not a service. Update expects to retrieve an entity manager instance but you don't provide it.
$up = new Update();
In a ContainerAware
class like a controller get your service like this:
$up = $this->container->get('update_command');
Otherwise turn the class where you want to use the update_command
into a service aswell and inject @update_command
as you did with the entity manager in the service itself.
remove below codes in app/config/config.yml, your services.yml will be autoload...
imports:
- { resource: "@projectprojBundle/Resources/config/services.yml" }
in a Action new a instance you can do:
$up = $this->get('update_command');