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

Cannot access custom repository not linked with any entity from controller in 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.

services.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

DefaultController.php:

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 有关更多详细信息,请参见:Having a custom repository not associated to an entity in Symfony 2 / Doctrine 2?

class CustomRepository
{
    private $em;
    private $rsm;

    /**
     * NativeQuery constructor.
     * @param EntityManagerInterface $em
     */
    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
        $this->rsm = new ResultSetMapping();
    }

    private function setResultFields($resultFieldsArray)
    {
        foreach ($resultFieldsArray as $columnName => $alias) {
            if (is_string($columnName)) {
                $this->rsm->addScalarResult($columnName, $alias);
            } else {
                $this->rsm->addScalarResult($alias, $alias);
            }
        }
    }

    public function executeQuery($query, $resultFieldsArray)
    {
        $this->setResultFields($resultFieldsArray);
        $exec = $this->em->createNativeQuery($query, $this->rsm);
        return $exec->execute();
    }


    app_bundle_custom_respository:
    class: AppBundle\Repository\CustomRepository
            arguments:
                $em: '@doctrine.orm.default_entity_manager'        
            public: true




/**
 * @Route("/test", name="test")
 * @return \Symfony\Component\HttpFoundation\Response
 */
public function test()
{
    $result = $this->container->get('app_bundle_custom_respository')->executeQuery('SELET * FROM table1', ['id', 'title', 'etc']);

我注入了 DBAL Connection 并完成了这项工作,因为我的唯一目的是使用 Connection 来执行原始 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;
    }
}