Каков самый чистый способ загрузки повторно используемых данных из репозитория?

У меня была панель меню в symfony, которая загружалась на каждый сайт в моем проекте. Обычно я загружаю данные следующим образом:

/**
 * @Route("", name = "main")
 * 
 * 
 */
public function main()
{
    $category_rep = $_om->getRepository(Category::class);
    $this->categories = $category_rep->findAll();
    ....
}

Это нормально, но я ищу лучшее решение для загрузки данных во весь контроллер или проект. Я нашел решение для автозагрузки данных:

@Entity("category", expr = "repository.find($id)")
public function index(Category $category)

но это может дать мне только один результат из объекта категории (в строке меню я хочу показать все категории в репозитории). Вторая идея заключалась в том, чтобы сделать конструктор в контроллере, который загружает эти данные следующим образом:

private $categories;

public function __construct(ObjectManager $_om)
{
    $category_rep = $_om->getRepository(Category::class);
    $this->categories = $category_rep->findAll();

}

или создайте службу, которая будет загружать эти данные и запускать эту службу в каждом методе. Я хочу спросить, какая из этих идей является лучшим («самым чистым») решением. Может быть, это другой лучший вариант??

Спасибо за помощь, Крис

Если вы хотите показать категории в строке меню, зачем вам все категории в whole controller or project? Разве недостаточно иметь его в действии контроллера, которое создает меню? Кстати, как вы строите свое меню? Можете ли вы вставить код для этого?

Michał Tomczuk 07.04.2019 20:43

У меня был файл base.html.twig, в котором у меня был основной шаблон с css и html, которые не меняются (одинаковое для каждого сайта в проекте, и у него не было метода контроллера), и я загружаю данные из других шаблонов блоком twig: {% body блока %}{% endblock %}. Хм, а идея сделать контроллер для базового шаблона и загружать туда эти данные... Я такой тупой :(

kris016 07.04.2019 21:11

Код базы в ярлыке выглядит так: <div class = "main-cointainer" ><div class = "menubar"></div> <div class = "content">{% block content %}{% endblock %}</div> </div> и я загружаю контент, используя '{% extends 'base.html.twig' %} {% block content %}{% endblock %}{% block content %}my content{% конечный блок %} '

kris016 07.04.2019 21:22

Спасибо за примеры кода. И не корите себя так, с такими знаниями никто не рождается ;) И если мой первый комментарий прозвучал немного снисходительно - извините.

Michał Tomczuk 07.04.2019 21:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
4
42
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Простым решением может быть отдельное действие контроллера для получения категорий для меню, например:

class MenuController extends AbstractController
{    
    public function displayMainMenu()
    {
        $categories = $this->getDoctrine()->getRepository(Category::class)->findAll();

        return $this->render('menu/main.html.twig', [
            'categories' => $categories,
        ]);
    }
}

который вернет частичный шаблон только с HTML-кодом меню, примерно так:

# menu/main.html.twig

{% for category in categories %}
    <div>
        <a href = "{{ path('/url/to/view/category/with/id', { id: category.id }) }}">
            {{ category.name }}
        </a>
    </div>
{% endfor %}

Теперь вам нужно только включить этот отрендеренный шаблон в свой base.html.twig от встраивание контроллера:

<div class = "menubar">
    {{ render(controller('App\\Controller\\MenuController\\displayMainMenu')) }}
</div>

Для более сложных меню вы можете рассмотреть возможность использования специального пакета, например KnpMenuBundle.

Большое спасибо... Я не думал сделать это таким образом

kris016 07.04.2019 21:47
Ответ принят как подходящий

Другим, также простым, но гораздо более элегантным (имхо) было бы создание пользовательская функция Twig, например:

class MenuExtension extends AbstractExtension
{
    private $categories;

    public function __construct(CategoryRepository $categories)
    {
        $this->categories = $categories;
    }

    public function getFunctions()
    {
        return [
            new TwigFunction(
                'main_menu',
                [$this, 'mainMenu'],
                ['needs_environment' => true]
            ),
        ];
    }

    public function mainMenu(\Twig_Environment $environment)
    {
        $categories = $this->categories->findAll();

        return $environment->render('menu/main.html.twig', [
            'categories' => $categories,
        ]);
    }
}

Конечно, вам также нужен шаблон для самого меню, как в предыдущем ответе:

# menu/main.html.twig

{% for category in categories %}
    <div>
        <a href = "{{ path('/url/to/view/category/with/id', { id: category.id }) }}">
            {{ category.name }}
        </a>
    </div>
{% endfor %}

Теперь вы можете использовать пользовательскую функцию в своем base.html.twig:

<div class = "menubar">
    {{ main_menu() }}
</div>

Другие вопросы по теме