Get service container from entity in symfony 2.1 (Doctrine)
An entity is a data model and should only hold data (and not have any dependencies on services). If you want to modify your model in case of a certain event (PrePersist in your case) you should look into making a Doctrine listener for that. You can inject the container when defining the listener:
services:
my.listener:
class: Acme\SearchBundle\Listener\YourListener
arguments: [@your_service_dependency_or_the_container_here]
tags:
- { name: doctrine.event_listener, event: prePersist }
Injectiong or accessing service container within an entity object
@Ahmend is correct in that you should not inject the container into entities. In your case you might do something like:
// Controller
$order = ...find($orderId);
$currency = $this->getContainer()->getParameter('currency');
$price = $order->calculatePrice($currency);
So currency is passed as a method parameter.I fully understand that this is a difficult concept especially if one is used to active records and plenty of globals. But in the end it will make sense and produce better code.
However, just so you don't get stuck, I will reveal onto you the secret of accessing the container from anywhere. Turns out that the app kernel is a global variable. So:
class Orders
{
public function getCurrency()
{
global $kernel;
$container = $kernel->getContainer();
return $container->getParameter('currency');
}
Get symfony parameter inside doctrine entity for lifecyclecallback
like @Cerad said, I solved it by defining the path as php class constant. That is even better style because the path should only be changed in very special cases and shouldn't be a parameter therefore.
Put a symfony container inside a repository or an entity is a good or bad practice?
There are some example of how to create Entity managers (or repository), relevant is as described in FOSUserBundle where doctrine Entity manager has been injected as object manager inside the Dependency injection.
if ('custom' !== $config['db_driver']) {
if (isset(self::$doctrineDrivers[$config['db_driver']])) {
$loader->load('doctrine.xml');
$container->setAlias('fos_user.doctrine_registry', new Alias(self::$doctrineDrivers[$config['db_driver']]['registry'], false));
} else {
$loader->load(sprintf('%s.xml', $config['db_driver']));
}
$container->setParameter($this->getAlias().'.backend_type_'.$config['db_driver'], true);
}
if (isset(self::$doctrineDrivers[$config['db_driver']])) {
$definition = $container->getDefinition('fos_user.object_manager');
$definition->setFactory(array(new Reference('fos_user.doctrine_registry'), 'getManager'));
}
In this case there are UserManager instead of repository that have the same role.In this example all services has been initialized and injected directly inside the dependency injection
It is more powerful to call (private) services directly inside the bundle construction / or "compilation" (the dependency injection) instead of colling container inside services
Creating a symfony service that can access doctrine
I believe that most people starting from scratch would use ORM, I didn't because I had existing PHP code working with PDO SQL. Here is an example showing how to access Doctrine DB connection:
In [YourBundle]\Resources\config\services.yml
services:
#dependency injection services
pdo_connection:
class: [YourBundle]\DependencyInjection\PDOManagement\PdoConnection
arguments: ["@doctrine.dbal.default_connection"]
Then in [YourBundle]\DependencyInjection\PDOManagement\PdoConnection.php<?php
namespace [YourBundle]\DependencyInjection\PDOManagement;
use Doctrine\DBAL;
class PdoConnection {
protected $db;
public function __construct($dbalConnection){
$this->db = $dbalConnection;
}
}
?>
this->db of class PdoConnection will have access to the DB connection after constructor.I let you figure out how to use it according to your need.
How to use my Entities and Entity Managers in Symfony 2 Console Command?
I think you should not retrieve the container in the constructor directly. Instead, retrieve it in the configure
method or in the execute
method. In my case, I get my entity manager just at the start of the execute
method like this and everything is working fine (tested with Symfony 2.1).
protected function execute(InputInterface $input, OutputInterface $output)
{
$entityManager = $this->getContainer()->get('doctrine')->getEntityManager();
// Code here
}
I think that the instantiation of the application object is not done yet when you are calling getContainer
in your constructor which result in this error. The error comes from the getContainer
method tyring to do:$this->container = $this->getApplication()->getKernel()->getContainer();
Since getApplication
is not an object yet, you get the a error saying or are calling a method getKernel
on a non-object.Update: In newer version of Symfony, getEntityManager
has been deprecated (and could have been removed altogether by now). Use $entityManager = $this->getContainer()->get('doctrine')->getManager();
instead. Thanks to Chausser for pointing it.
Update 2: In Symfony 4, auto-wiring can be used to reduce amount of code needed.
Create a __constructor
with a EntityManagerInterface
variable. This variable will be accessible in the rest of your commands. This follows the auto-wiring Dependency Injection scheme.
class UserCommand extends ContainerAwareCommand {
private $em;
public function __construct(?string $name = null, EntityManagerInterface $em) {
parent::__construct($name);
$this->em = $em;
}
protected function configure() {
**name, desc, help code here**
}
protected function execute(InputInterface $input, OutputInterface $output) {
$this->em->getRepository('App:Table')->findAll();
}
}
Credits to @profm2 for providing the comment and the code sample. Symfony2: Get Service Inside Entity
I don't know if you can but you shouldn't do it anyway. The entities are meant to be really simple...
What do you want to do exactly, there must be a different solution...need entity Manager inside entity so i can able to get custom result with repository functions
Related Topics
Error Starting Userland Proxy: Listen Tcp 0.0.0.0:3306: Bind: Address Already in Use
PHP Using Regex to Get Substring of a String
PHP Fatal Error: Call to Undefined Function Imagettftext()
PHP Gd: How to Get Imagedata as Binary String
How to Remove Backslash on JSON_Encode() Function
Download the Contents of a Url in PHP Even If It Returns a 404
Laravel Catch Eloquent "Unique" Field Error
Php: How to See "Invisible" Characters Like \N
How to Automatically Read in Calculated Values with PHPexcel
Object Copy Versus Clone in PHP
Converting Float Decimal to Fraction
Magento Products by Categories
Include Just Files in Scandir Array
How to Refresh Select2 Dropdown Menu After Ajax Loading Different Content
What's the Difference Between Post and Raw Post in PHP at All