Php 无法从symfony 3.4中的控制器访问未与任何实体链接的自定义存储库?

Php 无法从symfony 3.4中的控制器访问未与任何实体链接的自定义存储库?,php,symfony,doctrine-orm,symfony-3.4,Php,Symfony,Doctrine Orm,Symfony 3.4,我正在尝试访问包含自定义原始sql查询的自定义存储库,该存储库未链接到任何实体,但我遇到错误: Cannot autowire service "app_bundle_custom_respository": argument "$em" of method "Doctrine\ORM\EntityRepository::__construct()" has no type-hint, you should configure its value explicitly. 服务。yaml: #

我正在尝试访问包含自定义原始sql查询的自定义存储库,该存储库未链接到任何实体,但我遇到错误:

Cannot autowire service "app_bundle_custom_respository": argument "$em" of method "Doctrine\ORM\EntityRepository::__construct()" has no type-hint, you should configure its value explicitly.
服务。yaml:

# Learn more about services, parameters and containers at
# https://symfony.com/doc/current/service_container.html
parameters:
    #parameter_name: value

services:
    AppBundle\Twig\AppExtension:
        public: false
        tags: ['twig.extension']
    # default configuration for services in *this* file
    _defaults:
        # automatically injects dependencies in your services
        autowire: true
        # automatically registers your services as commands, event subscribers, etc.
        autoconfigure: true
        # this means you cannot fetch services directly from the container via $container->get()
        # if you need to do this, you can override this setting on individual services
        public: false

    # makes classes in src/AppBundle available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    AppBundle\:
        resource: '../../src/AppBundle/*'
        # you can exclude directories or files
        # but if a service is unused, it's removed anyway
        exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

    # controllers are imported separately to make sure they're public
    # and have a tag that allows actions to type-hint services
    AppBundle\Controller\:
        resource: '../../src/AppBundle/Controller'
        public: true
        tags: ['controller.service_arguments']

    # add more services, or override services that need manual wiring
    # AppBundle\Service\ExampleService:
    #     arguments:
    #         $someArgument: 'some_value'

    app_bundle_custom_respository:
        class: AppBundle\Repository\CustomRepository
        public: true
namespace AppBundle\Controller;

use AppBundle\Entity\EventType;
use AppBundle\Entity\VenueType;
use AppBundle\Repository\CustomRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\Testimonial;
use AppBundle\Form\TestimonialSearchForm;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;


class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        $categories = array();
        $eventTypes = $this->getDoctrine()->getRepository(EventType::class)->findAllSortedByName(4, true, true);
        foreach ($eventTypes as $eventType) {
            $categories[] = array(
                "type" => "events",
                "name" => $eventType->getName(),
                "slug" => $eventType->getSlug(),
                "image" => $eventType->getImage()
            );
        }
        $venueTypes = $this->getDoctrine()->getRepository(VenueType::class)->findAllSortedByName(4, true, true);
        foreach ($venueTypes as $venueType) {
            $categories[] = array(
                "type"  => "venues",
                "name"  => $venueType->getName(),
                "slug"  => $venueType->getSlug(),
                "image" => $venueType->getImage()
            );
        }
        $recentBlogs = $this->get('app_bundle_custom_respository');
        $recentBlogs = $recentBlogs->getLatestBlogPosts();
        return $this->render('default/index.html.twig', [
            'categories' => $categories,
            'recentBlogs' => $recentBlogs
        ]);
    }
}
namespace AppBundle\Repository;

use Doctrine\ORM\EntityRepository;

class CustomRepository extends EntityRepository
{
    /**
     * Get the latest blog posts
     *
     * @return mixed
     */
    public function getLatestBlogPosts()
    {
        $sql = "SELECT wp_posts.ID, wp_posts.post_title, wp_posts.post_content, wp_posts.guid FROM wp_posts WHERE  post_type = 'post' AND  post_status = 'publish' ORDER BY post_date DESC LIMIT 2";
        $em = $this->getEntityManager();
        $stmt = $em->getConnection()->prepare($sql);
        $stmt->execute();
        $recentBlogs = $stmt->fetchAll();
        foreach ($recentBlogs as $k => $recentBlog) {
            $sql = "SELECT meta_value as thumbnail_info FROM wp_postmeta WHERE post_id= (SELECT meta_value FROM wp_postmeta WHERE meta_key= '_thumbnail_id' AND post_id = " . $recentBlog['ID'] . ") AND meta_key = '_wp_attachment_metadata'";
            $stmt = $em->getConnection()->prepare($sql);
            $stmt->execute();
            $img = $stmt->fetchAll();
            if (isset($img[0]['thumbnail_info'])) {
                $thumbnail_data = unserialize($img[0]['thumbnail_info']);
                $upload_directory = explode('/', $thumbnail_data['file']);
                $recentBlogs[$k]['img'] = "/blog/wp-content/uploads/$upload_directory[0]/$upload_directory[1]/".$thumbnail_data['sizes']['medium']['file'];
            }
        }
        return $recentBlogs;
    }
}
DefaultController.php:

# Learn more about services, parameters and containers at
# https://symfony.com/doc/current/service_container.html
parameters:
    #parameter_name: value

services:
    AppBundle\Twig\AppExtension:
        public: false
        tags: ['twig.extension']
    # default configuration for services in *this* file
    _defaults:
        # automatically injects dependencies in your services
        autowire: true
        # automatically registers your services as commands, event subscribers, etc.
        autoconfigure: true
        # this means you cannot fetch services directly from the container via $container->get()
        # if you need to do this, you can override this setting on individual services
        public: false

    # makes classes in src/AppBundle available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    AppBundle\:
        resource: '../../src/AppBundle/*'
        # you can exclude directories or files
        # but if a service is unused, it's removed anyway
        exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

    # controllers are imported separately to make sure they're public
    # and have a tag that allows actions to type-hint services
    AppBundle\Controller\:
        resource: '../../src/AppBundle/Controller'
        public: true
        tags: ['controller.service_arguments']

    # add more services, or override services that need manual wiring
    # AppBundle\Service\ExampleService:
    #     arguments:
    #         $someArgument: 'some_value'

    app_bundle_custom_respository:
        class: AppBundle\Repository\CustomRepository
        public: true
namespace AppBundle\Controller;

use AppBundle\Entity\EventType;
use AppBundle\Entity\VenueType;
use AppBundle\Repository\CustomRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\Testimonial;
use AppBundle\Form\TestimonialSearchForm;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;


class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        $categories = array();
        $eventTypes = $this->getDoctrine()->getRepository(EventType::class)->findAllSortedByName(4, true, true);
        foreach ($eventTypes as $eventType) {
            $categories[] = array(
                "type" => "events",
                "name" => $eventType->getName(),
                "slug" => $eventType->getSlug(),
                "image" => $eventType->getImage()
            );
        }
        $venueTypes = $this->getDoctrine()->getRepository(VenueType::class)->findAllSortedByName(4, true, true);
        foreach ($venueTypes as $venueType) {
            $categories[] = array(
                "type"  => "venues",
                "name"  => $venueType->getName(),
                "slug"  => $venueType->getSlug(),
                "image" => $venueType->getImage()
            );
        }
        $recentBlogs = $this->get('app_bundle_custom_respository');
        $recentBlogs = $recentBlogs->getLatestBlogPosts();
        return $this->render('default/index.html.twig', [
            'categories' => $categories,
            'recentBlogs' => $recentBlogs
        ]);
    }
}
namespace AppBundle\Repository;

use Doctrine\ORM\EntityRepository;

class CustomRepository extends EntityRepository
{
    /**
     * Get the latest blog posts
     *
     * @return mixed
     */
    public function getLatestBlogPosts()
    {
        $sql = "SELECT wp_posts.ID, wp_posts.post_title, wp_posts.post_content, wp_posts.guid FROM wp_posts WHERE  post_type = 'post' AND  post_status = 'publish' ORDER BY post_date DESC LIMIT 2";
        $em = $this->getEntityManager();
        $stmt = $em->getConnection()->prepare($sql);
        $stmt->execute();
        $recentBlogs = $stmt->fetchAll();
        foreach ($recentBlogs as $k => $recentBlog) {
            $sql = "SELECT meta_value as thumbnail_info FROM wp_postmeta WHERE post_id= (SELECT meta_value FROM wp_postmeta WHERE meta_key= '_thumbnail_id' AND post_id = " . $recentBlog['ID'] . ") AND meta_key = '_wp_attachment_metadata'";
            $stmt = $em->getConnection()->prepare($sql);
            $stmt->execute();
            $img = $stmt->fetchAll();
            if (isset($img[0]['thumbnail_info'])) {
                $thumbnail_data = unserialize($img[0]['thumbnail_info']);
                $upload_directory = explode('/', $thumbnail_data['file']);
                $recentBlogs[$k]['img'] = "/blog/wp-content/uploads/$upload_directory[0]/$upload_directory[1]/".$thumbnail_data['sizes']['medium']['file'];
            }
        }
        return $recentBlogs;
    }
}
自定义存储库:

# Learn more about services, parameters and containers at
# https://symfony.com/doc/current/service_container.html
parameters:
    #parameter_name: value

services:
    AppBundle\Twig\AppExtension:
        public: false
        tags: ['twig.extension']
    # default configuration for services in *this* file
    _defaults:
        # automatically injects dependencies in your services
        autowire: true
        # automatically registers your services as commands, event subscribers, etc.
        autoconfigure: true
        # this means you cannot fetch services directly from the container via $container->get()
        # if you need to do this, you can override this setting on individual services
        public: false

    # makes classes in src/AppBundle available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    AppBundle\:
        resource: '../../src/AppBundle/*'
        # you can exclude directories or files
        # but if a service is unused, it's removed anyway
        exclude: '../../src/AppBundle/{Entity,Repository,Tests}'

    # controllers are imported separately to make sure they're public
    # and have a tag that allows actions to type-hint services
    AppBundle\Controller\:
        resource: '../../src/AppBundle/Controller'
        public: true
        tags: ['controller.service_arguments']

    # add more services, or override services that need manual wiring
    # AppBundle\Service\ExampleService:
    #     arguments:
    #         $someArgument: 'some_value'

    app_bundle_custom_respository:
        class: AppBundle\Repository\CustomRepository
        public: true
namespace AppBundle\Controller;

use AppBundle\Entity\EventType;
use AppBundle\Entity\VenueType;
use AppBundle\Repository\CustomRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\Testimonial;
use AppBundle\Form\TestimonialSearchForm;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;


class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        $categories = array();
        $eventTypes = $this->getDoctrine()->getRepository(EventType::class)->findAllSortedByName(4, true, true);
        foreach ($eventTypes as $eventType) {
            $categories[] = array(
                "type" => "events",
                "name" => $eventType->getName(),
                "slug" => $eventType->getSlug(),
                "image" => $eventType->getImage()
            );
        }
        $venueTypes = $this->getDoctrine()->getRepository(VenueType::class)->findAllSortedByName(4, true, true);
        foreach ($venueTypes as $venueType) {
            $categories[] = array(
                "type"  => "venues",
                "name"  => $venueType->getName(),
                "slug"  => $venueType->getSlug(),
                "image" => $venueType->getImage()
            );
        }
        $recentBlogs = $this->get('app_bundle_custom_respository');
        $recentBlogs = $recentBlogs->getLatestBlogPosts();
        return $this->render('default/index.html.twig', [
            'categories' => $categories,
            'recentBlogs' => $recentBlogs
        ]);
    }
}
namespace AppBundle\Repository;

use Doctrine\ORM\EntityRepository;

class CustomRepository extends EntityRepository
{
    /**
     * Get the latest blog posts
     *
     * @return mixed
     */
    public function getLatestBlogPosts()
    {
        $sql = "SELECT wp_posts.ID, wp_posts.post_title, wp_posts.post_content, wp_posts.guid FROM wp_posts WHERE  post_type = 'post' AND  post_status = 'publish' ORDER BY post_date DESC LIMIT 2";
        $em = $this->getEntityManager();
        $stmt = $em->getConnection()->prepare($sql);
        $stmt->execute();
        $recentBlogs = $stmt->fetchAll();
        foreach ($recentBlogs as $k => $recentBlog) {
            $sql = "SELECT meta_value as thumbnail_info FROM wp_postmeta WHERE post_id= (SELECT meta_value FROM wp_postmeta WHERE meta_key= '_thumbnail_id' AND post_id = " . $recentBlog['ID'] . ") AND meta_key = '_wp_attachment_metadata'";
            $stmt = $em->getConnection()->prepare($sql);
            $stmt->execute();
            $img = $stmt->fetchAll();
            if (isset($img[0]['thumbnail_info'])) {
                $thumbnail_data = unserialize($img[0]['thumbnail_info']);
                $upload_directory = explode('/', $thumbnail_data['file']);
                $recentBlogs[$k]['img'] = "/blog/wp-content/uploads/$upload_directory[0]/$upload_directory[1]/".$thumbnail_data['sizes']['medium']['file'];
            }
        }
        return $recentBlogs;
    }
}

您不应该扩展
EntityRepository

请参阅此处了解更多详细信息:

我注入了DBAL连接并完成了这项工作,因为我的唯一目的是使用连接执行原始sql查询

<?php

namespace AppBundle\Repository;

use Doctrine\DBAL\Connection;

class CustomRepository
{
    /**
    *
    * @var Connection
    */
    private $connection;
    public function __construct(Connection $dbalConnection)  {
        $this->connection = $dbalConnection;    
    }

    /**
     * Get the latest blog posts
     *
     * @return mixed
     */
    public function getLatestBlogPosts()
    {
        $sql = "SELECT wp_posts.ID, wp_posts.post_title, wp_posts.post_content, wp_posts.guid FROM wp_posts WHERE  post_type = 'post' AND  post_status = 'publish' ORDER BY post_date DESC LIMIT 2";
        $stmt = $this->connection->prepare($sql);
        $stmt->execute();
        $recentBlogs = $stmt->fetchAll();
        foreach ($recentBlogs as $k => $recentBlog) {
            $sql = "SELECT meta_value as thumbnail_info FROM wp_postmeta WHERE post_id= (SELECT meta_value FROM wp_postmeta WHERE meta_key= '_thumbnail_id' AND post_id = " . $recentBlog['ID'] . ") AND meta_key = '_wp_attachment_metadata'";
            $stmt = $this->connection->prepare($sql);
            $stmt->execute();
            $img = $stmt->fetchAll();
            if (isset($img[0]['thumbnail_info'])) {
                $thumbnail_data = unserialize($img[0]['thumbnail_info']);
                $upload_directory = explode('/', $thumbnail_data['file']);
                $recentBlogs[$k]['img'] = "/blog/wp-content/uploads/$upload_directory[0]/$upload_directory[1]/".$thumbnail_data['sizes']['medium']['file'];
            }
        }
        return $recentBlogs;
    }
}

@TarasV:谢谢,但您提供的链接是针对用于扩展您当前实体的存储库,但我的存储库与任何实体都没有关系。条令存储库需要指向实体的链接。事情就是这样。您创建了一个不扩展EntityRepository的类,只注入实体管理器或数据库连接对象。@Cerad:实际上,此存储库没有可链接到的实体。我想要的是有一个自定义类,我可以在其中保存原始的基于sql的查询,这些查询从数据库中获取不同类型的内容?也可以在控制器中轻松访问该类?这似乎没有多大意义。Doctrine ORM包中的基本
EntityRepository
要求您向其传递一个
ClassMetadata
实例。但是,如果您的存储库没有链接到任何实体,您会从哪个实体传递这些信息?看看你的repository类做了什么,我不会扩展
EntityRepository
类,只会注入一个执行SQL查询所需的
连接
实例。谢谢你的回答,但我注入了DBAL连接并完成了这项工作。