【问题标题】:Symfony | How to access the custom methods from the respository in a controller?Symfony |如何从控制器中的存储库访问自定义方法?
【发布时间】:2019-04-28 21:19:21
【问题描述】:

我正在设置一个清单来练习使用 Symfony 构建 Web 应用程序。它通过在表单中​​输入字符串并按下提交按钮来工作。输入存储在数据库中。

我想将存储在数据库中的输入返回到网页。

目前,输入存储在数据库中,我已经在我的存储库中编写了一个用于 DQL 查询的函数。

我的问题是我无法访问我在控制器中创建的方法。

我的仓库中的方法:

    /**
     * @return Checklist[]
     */
    public function getAllItemsForChecklist(): array
    {
        $qb = $this->createQueryBuilder('c')
            ->select('item')
            ->from('checklist', 'x') 
            ->getQuery()
        ;

        return $qb->execute();
    }

尝试访问控制器中方法的行(失败):

$items = $this->getDoctrine()
    ->getRepository(ChecklistRepository::class)
    ->getAllItemsForChecklist()
;

根据https://symfony.com/doc/master/doctrine.html#querying-for-objects-the-repository 的 Symfony 文档,这应该可以工作。但是,找不到方法“getAllItemsForChecklist()。在我的 IDE 上给出了以下消息:

在 \Doctrine\Common\Persistence\ObjectRepository 中找不到方法“getAllItemsForChecklist”

我不确定为什么它没有读取我指定的存储库类。

如果有人知道如何解决这个问题,那么它将在我的存储库中找到我制作的方法,将不胜感激。

另外,如果需要任何额外信息,请告诉我,我很乐意提供更多信息。

问候,

史蒂夫

【问题讨论】:

    标签: php symfony doctrine dql


    【解决方案1】:

    欢迎来到 StackOverflow!

    首先,当您调用getRepository() 时,您必须传递实体类,而不是存储库本身,所以它会是这样的:

    $this->getDoctrine()->getRepository(Checklist::class);

    即使您这样做,您的 IDE 也不会知道该方法存在。你的IDE其实是错的,方法确实存在,只是你的IDE无法知道getRepository()调用返回了什么对象。

    如何避免这种情况?选择其中一种解决方案(它们都适用于 PhpStorm,选项 1 应该适用于任何地方,选项 2 可能适用于所有现代 IDE,我不知道其他 IDE 是否支持选项 3):

    选项 1:将其作为服务注入

    public function myControllerRoute(ChecklistRepository $checklistRepository) {
        // now your IDE knows what methods are inside the $checklistRepository
        $items = $checklistRepository->getAllItemsForChecklist();
    }
    

    选项 2:向 IDE(和其他开发人员)输入提示

    public function myControllerRoute() {
        /** @var ChecklistRepository $checklistRepository */
        $checklistRepository = $this->getDoctrine()->getRepository(Checklist::class);
    
        // after the typehint the IDE knows what type it is
        $items = $checklistRepository->getAllItemsForChecklist();
    }
    

    选项 3:使用断言

    public function myControllerRoute() {
        $checklistRepository = $this->getDoctrine()->getRepository(Checklist::class);
        assert($checklistRepository instanceof ChecklistRepository);
    
        // after the assert the IDE knows what type it is
        $items = $checklistRepository->getAllItemsForChecklist();
    }
    

    选项 2 和 3 几乎相同,但是选项 3 有一个额外的好处,即在开发机器上,如果 $checklistRepository 不是 ChecklistRepository 的实例,它将抛出异常,而在生产环境中 assert() 调用将被忽略并且完全不减慢执行速度。

    【讨论】:

    • 提供的解决方案有效,但出于好奇,我的原始代码是否有效,因为问题是 IDE,而不是我的代码?
    • @RushTheFox 不,正如我在我的编辑之一中澄清的那样,在您对getRepository() 的调用中,您需要包含实体类,而不是存储库本身,例如getRepository(Checklist::class) 而不是 getRepository(ChecklistRepository::class)
    • @RushTheFox 还有,你最后用的是什么方案?
    • 我使用了选项 3,现在遇到了映射异常,但我希望能够找出原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 2012-07-28
    • 2015-11-24
    • 2021-03-18
    相关资源
    最近更新 更多