Symfony调用Controller方法出现Call to a member function has() on null错误
解决Symfony中Twig扩展调用Controller方法时
$this->container为null的问题 你遇到的Call to a member function has() on null错误,根源在于直接将Controller注入Service时,Symfony并未初始化Controller的容器依赖。Controller默认由Symfony的控制器解析器负责实例化,这个过程会自动注入$container等核心依赖,但手动把Controller注入其他服务时,初始化流程不会触发,导致$this->container为null,进而调用getDoctrine()失败。
正确的做法是将Controller中的业务逻辑抽离到独立Service,让Twig扩展和Controller复用同一个Service的逻辑,既符合Symfony的架构设计,也能解决依赖问题。具体步骤如下:
1. 抽离业务逻辑到独立Service
创建专门处理购物车图片逻辑的Service,把CartController::image_route中的数据查询、处理逻辑迁移过来:
// src/Service/CartImageService.php namespace App\Service; use Doctrine\ORM\EntityManagerInterface; use App\Entity\YourImageEntity; // 替换成你的实体类 class CartImageService { private $entityManager; public function __construct(EntityManagerInterface $entityManager) { $this->entityManager = $entityManager; } public function getCustomImages() { // 原CartController中image_route方法里的查询逻辑 $customImages = $this->entityManager ->getRepository(YourImageEntity::class) ->findBy(['status' => 'active']); // 替换成你的查询条件 // 可添加数据处理逻辑,比如格式化URL等 return $customImages; } }
2. 修改CartController,复用Service逻辑
让CartController注入刚才创建的Service,原来的image_route方法直接调用Service获取数据:
// src/Controller/CartController.php namespace App\Controller; use App\Service\CartImageService; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; class CartController extends AbstractController { private $cartImageService; public function __construct(CartImageService $cartImageService) { $this->cartImageService = $cartImageService; } public function image_route() { $customImages = $this->cartImageService->getCustomImages(); return $this->render('cart/images.html.twig', [ 'custom_images' => $customImages, ]); } }
3. 在Twig扩展中注入Service
修改你的Twig扩展,直接注入CartImageService,通过自定义Twig函数暴露数据:
// src/Twig/CartImageExtension.php namespace App\Twig; use App\Service\CartImageService; use Twig\Extension\AbstractExtension; use Twig\TwigFunction; class CartImageExtension extends AbstractExtension { private $cartImageService; public function __construct(CartImageService $cartImageService) { $this->cartImageService = $cartImageService; } public function getFunctions() { return [ new TwigFunction('get_cart_custom_images', [$this, 'getCustomImages']), ]; } public function getCustomImages() { return $this->cartImageService->getCustomImages(); } }
4. 在Twig模板中使用
现在可以直接在任意Twig模板中调用自定义函数获取数据:
{% set custom_images = get_cart_custom_images() %} {% for image in custom_images %} <img src="{{ asset(image.filePath) }}" alt="{{ image.title }}"> {% endfor %}
这种方式不仅解决了容器为null的问题,还遵循了Symfony的"关注点分离"原则——Controller只负责处理请求响应,业务逻辑放在Service中复用,Twig扩展专注于模板扩展功能。
内容的提问来源于stack exchange,提问作者maz32
相关产品推荐
相关产品推荐

