Я читал много тем об этом, и я не могу найти решение моей проблемы.
Я чувствую, что проблема очевидна, и, возможно, я просто слишком долго смотрел на нее.
Ошибка: FatalErrorException: Ошибка: вызов функции-члена имеет () для не-объекта в строке /vagrant/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php 198
Говорит об ошибке.
public function getDoctrine() { if (!$this->container->has('doctrine')) { throw new \LogicException('The DoctrineBundle is not registered in your application.'); } return $this->container->get('doctrine'); }
Вот мой код …
Это главный контроллер, вызывающий контроллер DAO
public function clickThroughAction(request $request, $hash) { if (isset($hash)) { $dbController = $this->get('database_controller'); print_r($dbController->getReferralIdByHash($hash)); return $this->redirect($this->generateUrl('home')); } else { return 0; } }
Это сервис, который используется.
services: database_controller: class: Fuel\FormBundle\Controller\DatabaseController
Это контроллер dao, вызывающий базу данных.
public function getReferralIdByHash($hash) { $em = $this->getDoctrine()->getManager(); $query = $em->createQuery( 'Select u From FuelFormBundle:UserReferrals u WHERE u.user_hash = :hash' )->setParameter('hash', $hash); $referral = $query->getResult(); if (!$referral) { throw $this->createNotFoundException( 'No product referral found' ); $logger = $this->get('logger'); $logger->info('I just got the logger'); $logger->crit('An error occurred, hash for referrals is not recognized. current hash is: ' . $hash . " ."); return $this->redirect($this->generateUrl('home')); } $clickThroughCount = $referral[0]->getClickThrough(); $referral[0]->setClickThrough($clickThroughCount + 1); $em->flush(); return $referral; }
Я думаю, проблема в том, что контейнера доктрины нет, поэтому у меня возникают проблемы. Я не уверен, как это решить.
Любая помощь приветствуется. Благодаря!
редактировать
Хорошо, вот что я изменил.
Главный контроллер остался прежним.
DAO Controller добавлено несколько вещей.
class DatabaseController extends Controller{ protected $entityManager; public function __construct($entityManager) { $this->entityManager = $entityManager; } public function getReferralIdByHash($hash) { $em = $this->entityManager; $query = $em->createQuery( 'Select u From FuelFormBundle:UserReferrals u WHERE u.user_hash = :hash' )->setParameter('hash', $hash); $referral = $query->getResult(); if (!$referral) { throw $this->createNotFoundException( 'No product referral found' ); $logger = $this->get('logger'); $logger->info('I just got the logger'); $logger->crit('An error occurred, hash for referrals is not recognized. current hash is: ' . $hash . " ."); return $this->redirect($this->generateUrl('home')); } $clickThroughCount = $referral[0]->getClickThrough(); $referral[0]->setClickThrough($clickThroughCount + 1); $em->flush(); return $referral; } }
Служба оказалась похожей на эту
services: database_controller: class: Fuel\FormBundle\Controller\DatabaseController arguments: ["@doctrine.orm.entity_manager"]
Проблема заключается в том, что контейнер не вводится в контроллер здесь.
Обычно Symfony делает это автоматически, если вы расширяете Symfony\Bundle\FrameworkBundle\Controller\Controller
, который сам расширяет Symfony\Component\DependencyInjection\ContainerAware
:
use Symfony\Bundle\FrameworkBundle\Controller\Controller; class YourController extends Controller
Контейнер впрыскивается в контроллер (если он явно не определен как услуга), используя инъекцию установщика, вызывающую метод setContainer()
с контейнером в качестве аргумента.
Теперь, когда вы настроили свой контроллер как услугу, вам нужно добавить вызов setContainer в конфигурацию вашего сервиса:
services: database_controller: class: Fuel\FormBundle\Controller\DatabaseController calls: - [setContainer, ["@service_container"]]
Очистите свой кеш после этого.
Не знаете, почему вы должны сделать диспетчер услугой. Для какого случая? Обычно служба представляет собой обычный объект PHP.
О вашей проблеме .. поскольку вы используете контроллер в качестве службы, он не получает контейнер автоматически. Таким образом, вы должны ввести весь контейнер, который является тяжелым, если вам просто нужна доктрина.
Так что лучше просто ввести то, что вам действительно нужно. Чтобы ввести доктрину в свой yml ниже class:
arguments: ["@doctrine.orm.entity_manager"]
Затем в вашем контроллере контроллера:
public function __construct($entityManager) { $this->entityManager = $entityManager; }
Возможно, вам понадобится вызвать родительский конструктор (помните об этом).
Если вы хотите, все равно вливайте полный контейнер обслуживания, вот в этом разделе, как вы можете это сделать: http://symfony.com/doc/current/cookbook/service_container/scopes.html#passing-the-container ая-а-зависимости из-вашей-службы
Еще одно предположение: когда вы перемещаете соединение с базой данных из основного контроллера, вам нужно, например, построить новый экземпляр Entity Manager:
class StoreController extends Controller{ public function addstoreAction(Request $request){ $checkStore = new StoreExistsCheck($this ->getDoctrine()->getManager()); //your code here }
с использованием папки / myBundle / Model
namespace myBundle\Model; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use myBundle\Entity\Store; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Query; class StoreExistsCheck extends Controller{ protected $em = null; protected $kernel = null; public function __construct(EntityManager $em) { $this->em = $em; } public function storeExists($argosStore){ $storeExists = $this->em ->getRepository('myBundle:Store') ->findOneBystoreNumber($argosStore->getStoreNumber()); return $storeExists; }