无法从 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;
}
}
我正在尝试访问包含自定义原则原始 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;
}
}