Symfony 4 - KnpPaginator Bundle “service not found

2019-04-24 14:20发布

I have been following tutorials, and all instructions show it's done the exact same way, but it doesn't seem to work in Symfony 4. Is there something I'm overlooking or is the bundle simply incompatible?

I ran: composer require knplabs/knp-paginator-bundle

It was loaded automatically into bundles.php, thanks to Flex.

Inserted the following into config/services.yaml:

knp_paginator:
    page_range:                 5          # default page range used in pagination control
    default_options:
        page_name:              page       # page query parameter name
        sort_field_name:        sort       # sort field query parameter name
        sort_direction_name:    direction  # sort direction query parameter name
        distinct:               true       # ensure distinct results, useful when ORM queries are using GROUP BY statements
    template:
        pagination: KnpPaginatorBundle:Pagination:twitter_bootstrap_v3_pagination.html.twig     # sliding pagination controls template
        sortable: KnpPaginatorBundle:Pagination:sortable_link.html.twig                         # sort link template

Tried to use the following in the controller:

$paginator  = $this->get('knp_paginator');

and got the following error:

Service "knp_paginator" not found: even though it exists in the app's container, the container inside "App\Controller\PhotoController" is a smaller service locator that only knows about the "doctrine", "form.factory", "http_kernel", "request_stack", "router", "security.authorization_checker", "security.token_storage", "serializer", "session" and "twig" services. Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "PhotoController::getSubscribedServices()".

3条回答
劳资没心,怎么记你
2楼-- · 2019-04-24 14:59

As it says in the documentation. You must extend the base Controller class, or use dependency injection instead https://symfony.com/doc/current/service_container.html#service-parameters

查看更多
干净又极端
3楼-- · 2019-04-24 15:03

In my case I use AbstractController and as malcolm says, it is beter to inject the service directrly in your action, even so, I call a method several times and I think that overwrite getSubscribedServices is clener for my porpuse.

public static function getSubscribedServices(): array
{
    $services = parent::getSubscribedServices();
    $services['fos_elastica.manager'] = RepositoryManagerInterface::class;
    $services['knp_paginator'] = PaginatorInterface::class;

    return $services;
}

private function listHandler(Search $search, Request $request, int $page): Response
{
    //...
    $repository = $this->container->get('fos_elastica.manager')->getRepository(Foo::class);
    //...

}
查看更多
Melony?
4楼-- · 2019-04-24 15:17

You have to extend Controller instead of AbstractController class:

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class MyController extends Controller
{

    public function myAction()
    {
        $paginator  = $this->get('knp_paginator');

or better leave AbstractController and inject knp_paginator service into your action:

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Knp\Component\Pager\PaginatorInterface;

class MyController extends AbstractController
{

    public function myAction(PaginatorInterface $paginator)
    {
        $paginator->paginate()...
    }
查看更多
登录 后发表回答