7

我已经阅读了很多关于此的主题,但我似乎无法找到解决我的问题的方法。

我觉得问题很明显,也许我只是盯着它太久了。

错误是 FatalErrorException: Error: Call to a member function has() on a non-object in /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 控制器添加了一些东西。

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"]
4

3 回答 3

23

问题是容器没有被注入到这里的控制器中。

通常,如果您正在扩展,Symfony 会自动执行此操作Symfony\Bundle\FrameworkBundle\Controller\Controller,而扩展本身就是扩展Symfony\Component\DependencyInjection\ContainerAware

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class YourController extends Controller

容器被注入到控制器中(如果没有明确定义为服务),使用setter injection调用setContainer()容器作为参数的方法。

现在,当您将控制器配置为服务时,您需要将 setContainer 调用添加到服务配置中:

services:
    database_controller:
        class:  Fuel\FormBundle\Controller\DatabaseController
        calls:
            - [setContainer, ["@service_container"]]

之后清除缓存。

于 2013-10-09T21:52:55.877 回答
1

不知道为什么要将控制器作为服务。用于什么用例?通常,服务是一个普通的旧 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 -作为服务的依赖项

于 2013-10-09T21:02:03.570 回答
1

还有一个建议:当您将数据库连接移出主控制器时,您需要构建实体管理器的新实例,例如:

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;

} 
于 2014-02-24T12:05:54.223 回答