У меня есть файл DefaultRepository, в котором можно разместить все общие запросы.
Можно ли иметь собственный репозиторий, не связанный с сущностью в Symfony? Я хотел бы добавить в него собственный SQL, который не подходит для других репозиториев (он может относиться к абстрактной или иерархии сущностей).
Как код контроллера:
$this->getDoctrine()->getRepositoty(/* ??? */) should be replaced?
Что вы имеете в виду под «родным SQL»? Пожалуйста, более конкретно опишите, что вы хотите сделать. Например, вы можете добавить немного сахара с помощью создания и обработки QueryBuilder.




У вас может быть собственный общий «репозиторий», но вы не сможете получить его через Doctrine EntityManager. Вместо этого вы вводите его непосредственно в контроллер.
Ваш репозиторий может выглядеть примерно так:
class MyRepository implements RepositoryInterface
{
private $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public function findFoo()
{
$builder = $this->entityManager->createQueryBuilder();
$query = $builder->... // build query
return $query->getResult();
}
// Implement the generic find-methods defined by the interface
}
Реализация интерфейса не является обязательной, когда вы используете репозиторий напрямую, но сделает его более знакомым. Введя entityManager, вы можете просто вызвать другие репозитории для получения данных или создать построитель запросов для написания ваших собственных запросов.
Затем в вашем контроллере вы должны ввести репозиторий или получить его из контейнера, например нравится:
class FooController extends Controller
{
private $repository;
public function __construct(MyRepository $repository)
{
$this->repository = $repository;
}
public function indexAction(Request $request)
{
$foo = $this->repository->findFoo();
}
}
Вы также можете определить свой репозиторий как службу:
# app/config/services.yml
services:
app.my_repository:
class: App\Repository\MyRepository
arguments:
- '@doctrine.orm.entity_manager'
а затем получить ваш репозиторий в контроллерах с помощью вспомогательного метода, вместо того, чтобы вводить его:
$this->get('app.my_repository');
Обратите внимание, что:
findOneBy имеет смысл, возможно, имеет смысл не реализовывать интерфейс.FindFooQuery, который вы вводите в качестве службы в свой контроллер. Таким образом становится более ясно, что это на самом деле не связано с какой-либо сущностью, но это что-то свое. Это может сделать этот подход более управляемым, когда у вас много запросов.Я использую эту строку в контроллере: $ query = $ this-> get ('app.my_repository') -> searchAdvance ($ var, $ var1, $ var2, $ var3); Но это ошибка: «Ошибка типа: слишком мало аргументов для функции Doctrine \ ORM \ EntityRepository :: __ construct (), 1 передан в / var / www / html / amalia / var / cache / dev / appDevDebugProjectContain er.php on строка 431 и ожидается ровно 2 "В чем ошибка?"
Вам необходимо настроить репозиторий на вашем services.yml. Кажется, у вас есть 2 аргумента вместо 1 в моем примере. Если у вас более новая версия Symfony (3.4 или 4.0 и выше), вы можете использовать для этого автоматическое подключение: symfony.com/doc/current/service_container/autowiring.html В противном случае вам придется настроить конфигурацию, которую я добавил выше.
Вам нужен не репозиторий. Репозиторий связан с Entity в Doctrine и предоставляет такие функции, как findOneBy и т. д. Вне контекста сущности это не имеет смысла. Если вам нужно хранить пользовательские запросы, вы все равно можете добавить службу и внедрить в нее Doctrine Manager (или только нужные вам репозитории сущностей). Затем вы можете легко использовать свой сервис в контроллере.
В вашем файле services.yaml у вас будет что-то вроде этого:
services:
App\Services\QueriesManager:
autowire: true
Ваша служба будет выглядеть так (App \ Services \ QueriesManager)
<?php
namespace App\Services;
use Doctrine\ORM\EntityManagerInterface;
class QueriesManager {
protected $entityManager;
__construct(EntityManagerInterface $entityManager) {
$this->entityManager = $entityManager;
}
public function getSpecialQueryResult() {
$qb = $this->entityManager->createQueryBuilder();
$qb->select(...)
->where(...)
return $qb->getQuery()->getResult();
}
}
А в вашем контроллере вы можете просто напечатать намек на метод, который вы хотите использовать, например:
class MyController {
public function indexAction($param1, \App\Services\QueriesManager $queriesManager) {
return $queriesManager->getSpecialQueryResult();
}
}
Это ошибка: «Примечание: неопределенная переменная: queryManager». В чем проблема?
Вероятно, у вас где-то есть опечатка ... Отсутствует "$" или что-то в этом роде.
Это не работает так, как вы указываете для вызова с контроллера, на данный момент у меня это так: $ query = $ em-> getRepository ('BackendBundle: Users') -> searchAdvance ($ va r, $ var1, $ var2, $ var3) ; Но как это было бы использовать ваше решение?
Мое решение полагается на автоматическое подключение для внедрения службы. Сервис не является репозиторием, поэтому вы не можете вызвать его из метода $ em-> getRepository.
Ok. Теперь я использую службу в контроллере: $ query = $ this-> get ('app.queriesmanager') -> searchAdvance ($ var, $ var1, $ var2, $ var3); но показать эту ошибку: «Ошибка типа: аргумент 1, переданный в AppBundle \ Services \ QueriesManager :: __ construct (), должен реализовывать интерфейс Doctrine \ ORM \ EntityManagerInterface, экземпляр Symfony \ Component \ HttpFoundation \ Session \ Session, указанный в / var / www / html / amalia / var / cache / dev / appDevDebugProjectContain er.php в строке 532 "Строка такова: публичная функция __construct (EntityManagerInterface $ entityManager) {// File QueriesManager.php
Спасибо за ответы.
Это решение для меня: https://stackoverflow.com/a/53098008/2400373
Используйте symfony 3.3.x Здесь я кратко описываю, как решить мою проблему.
Файл service.yml:
//service.yml
services:
app.queriesmanager:
class: AppBundle\Services\QueriesManager
autowire: true
Файл AppBundle \ Services \ QueriesManager.php
//AppBundle\Services\QueriesManager.php
<?php
namespace AppBundle\Services;
use Doctrine\ORM\EntityManagerInterface;
class QueriesManager {
protected $entityManager;
public function __construct(EntityManagerInterface $entityManager) {
$this->entityManager = $entityManager;
}
public function searchAdvance($var,$var1,$var2,$var3)
{
$dql1 = "";
$dql2 = "";
$dql = "SELECT pl
FROM BackendBundle:Products p
JOIN BackendBundle:Pricelist pl
WITH p.peachitemid = pl.peachitemid
WHERE p.hasimages = 1
AND p.active = 'FALSE'
AND p.imagesamazon1 = 1
AND p.imagesamazon2 = 1
AND (p.descriptionforsales like '%$var%' OR p.itemid like '%$var%')";
if ($var1 != "select") {
$dql1 = " AND p.newcategory='$var1' AND p.newsubcategory='$var2' ";
}
if ($var3 == "150") {
$dql2 = " AND pl.retail < 150";
}
if ($var3 == "200") {
$dql2 = " AND pl.retail > 150 AND pl.retail < 250 ";
}
if ($var3 == "250") {
$dql2 = " AND pl.retail > 250 ";
}
$dql1 .= $dql2;
$dql .= $dql1;
$query=$this->entityManager->createQuery($dql);
$query = $query->getResult();
return $query;
}
}
Файл DefaultController.php
//Use the service in controller
$query=$this->get('app.queriesmanager')->searchAdvance($var,$var1,$var2,$var3);
Обновлять
Для symfony 4.x вам нужно изменить строки в сервисе
app.queriesmanager:
class: App\Services\QueriesManager
public: true
Спасибо вам, и я надеюсь, что вы можете помочь.
Залить репозиторий. Вы не должны использовать getRepo для чего-либо, что достаточно актуально.