You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony3.4自定义控制器调用getDoctrine()报has() on null错误如何解决?

问题根因

错误由两个核心原因触发:

  1. Symfony 控制器的容器注入逻辑晚于构造函数执行,你在__construct中调用依赖容器的getDoctrine()方法时,容器还未完成注入,处于null状态,因此调用has()方法时报错。
  2. 你虽然在service.yml中声明了注入EntityManager,但未在构造函数中接收该参数,依然调用依赖容器的getDoctrine(),服务注册配置完全没有生效。
修复方案

方案一:使用构造函数注入EntityManager(推荐)

直接利用你已经配置的服务注入逻辑,修改CustomController代码接收构造函数参数,无需再调用依赖容器的getDoctrine():

<?php

namespace AppBundle\Controller;

use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;


class CustomController extends Controller
{
    public $data = [];
    protected $em;


    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
        $countAttente = $this->em->getRepository('AppBundle:Commandes')->tailleEnAttente("En attente");
        
        $this->data['countAttente'] = $countAttente;
    }
}

你原来的service.yml配置可以简化为:

AppBundle\Controller\CustomController:
        arguments: ["@doctrine.orm.entity_manager"]

注意:所有继承CustomController的子控制器如果有自定义构造函数,需要调用parent::__construct($em),同时子控制器也需要注册为服务,传递EntityManager参数。

方案二:将逻辑移到setContainer方法中

如果不想修改所有子控制器的服务配置,可以重写父类的setContainer方法,等容器注入完成后再执行查询逻辑:

<?php

namespace AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;


class CustomController extends Controller
{
    public $data = [];
    protected $em;

    public function setContainer(ContainerInterface $container = null)
    {
        parent::setContainer($container);
        // 此时容器已注入完成,可正常调用getDoctrine()
        $this->em = $this->getDoctrine()->getManager();
        $countAttente = $this->em->getRepository('AppBundle:Commandes')->tailleEnAttente("En attente");
        
        $this->data['countAttente'] = $countAttente;
    }
}

该方案不需要修改service.yml配置,也不需要调整子控制器的代码,适配性更强。

方案三:用Twig全局变量实现(菜单通知类需求最优解)

如果你的统计值只需要在模板中展示,完全不需要耦合到控制器父类,直接配置Twig全局变量更简洁:

  1. 创建独立服务处理统计逻辑:
// src/AppBundle/Service/OrderCounter.php
namespace AppBundle\Service;

use Doctrine\ORM\EntityManagerInterface;

class OrderCounter
{
    protected $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public function getPendingCount()
    {
        return $this->em->getRepository('AppBundle:Commandes')->tailleEnAttente("En attente");
    }
}
  1. 在service.yml中注册服务并配置为Twig全局变量:
services:
    AppBundle\Service\OrderCounter:
        arguments: ["@doctrine.orm.entity_manager"]

twig:
    globals:
        order_counter: '@AppBundle\Service\OrderCounter'
  1. 所有Twig模板中都可以直接调用{{ order_counter.pendingCount }}获取统计值,不需要修改控制器逻辑。

内容的提问来源于stack exchange,提问作者Silkosmaniak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 13:36:00