个性化阅读
专注于IT技术分析

如何解决Symfony 4中的KnpPaginator异常:即使应用容器中存在服务”knp_paginator”,也找不到

此异常出现在使用早期版本(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
        ));
    }
}

编码愉快!

赞(0)
未经允许不得转载:srcmini » 如何解决Symfony 4中的KnpPaginator异常:即使应用容器中存在服务”knp_paginator”,也找不到

评论 抢沙发

评论前必须登录!