此异常出现在使用早期版本(Symfony 3)中的代码的Symfony 4项目中, 其中通过服务容器请求服务, 例如, 以下控制器应引发异常:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use ReCaptcha\ReCaptcha;
use Doctrine\ORM\Query\Expr\Join;
use App\Entity\FosUser;
// Note as well that extends the 'Symfony\Bundle\FrameworkBundle\Controller\Controller' class
// which is deprecated in Symfony 4
class AuthorsController extends Controller
{
// Controller that shows all the news from x repository
public function show(Request $request, FosUser $user){
$em = $this->getDoctrine()->getManager();
$repoArticles = $em->getRepository('App:News');
$pagination = $repoArticles->createQueryBuilder('a')
->where('a.published = 1')
->andWhere('a.author = :user')
->orderBy('a.datepublished', 'DESC')
->setParameter('user', $user->getId())
->getQuery()
->getResult();
// Important: and paginates the query with knp paginator, however accesing the service container
$paginator = $this->get('knp_paginator');
$entities = $paginator->paginate($pagination, $request->query->getInt('page', 1), 14);
return $this->render('news/show.html.twig', array(
'user' => $user, 'entities' => $entities
));
}
}
代码中描述的问题是由你尝试访问KNP的分页器服务引起的。在本文中, 我们将向你简要介绍如何在Symfony 4项目中解决此异常。
解
基本上, 解决此问题所需要做的是分析现有代码, 并从何处请求分页器服务。如果从服务容器中需要它, 则需要删除该变量, 并将PaginatorInterface直接注入控制器。这将公开与在服务容器中工作方式相同的变量, 还要注意, 控制器需要扩展AbstractController类, 而不是Controller类, 因为这将防止将来的弃用警告:
<?php
namespace App\Controller;
// 1. Include the AbstractController class
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
// 2. The controller extends now the AbstractController
class ExampleController extends AbstractController
{
// 3. The paginator is injected in the action $paginator
public function exampleaction(PaginatorInterface $paginator){
$em = $this->get('doctrine.orm.entity_manager');
$dql = "SELECT a FROM AcmeMainBundle:Article a";
$query = $em->createQuery($dql);
// 3. Use paginator to do something with the paginator
$pagination = $paginator->paginate(
$query, /* query NOT result */
$request->query->getInt('page', 1), /*page number*/
10 /*limit per page*/
);
}
}
我们的例子的解决方案
以下代码段显示了如何通过AbstractController的实现正确修复初始示例, 以及如何将分页器直接插入动作中:
<?php
namespace App\Controller;
// Use the abstract controller instead
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use ReCaptcha\ReCaptcha;
use Doctrine\ORM\Query\Expr\Join;
use App\Entity\FosUser;
// The controller extends now the AbstractController
class AuthorsController extends AbstractController
{
// Controller that shows all the news from x repository
// The paginator is injected in the action $paginator
public function show(Request $request, FosUser $user, PaginatorInterface $paginator){
$em = $this->getDoctrine()->getManager();
$repoArticles = $em->getRepository('App:News');
$pagination = $repoArticles->createQueryBuilder('a')
->where('a.published = 1')
->andWhere('a.author = :user')
->orderBy('a.datepublished', 'DESC')
->setParameter('user', $user->getId())
->getQuery()
->getResult();
$entities = $paginator->paginate($pagination, $request->query->getInt('page', 1), 14);
return $this->render('news/show.html.twig', array(
'user' => $user, 'entities' => $entities
));
}
}
编码愉快!
评论前必须登录!
注册