Symfony: Как заставить переменную работать на каждой странице?

У меня есть вопрос по моему проекту Symfony.

У меня есть этот код, который показывает количество строк в данной таблице базы данных:

// BudgetRepository
public function countBudgets()
{
  $qb = $this->createQueryBuilder('budget');
  return $qb
    ->select('count(budget.id)')
    ->getQuery()
    ->getSingleScalarResult();
}
// BudgetController
public function all(EntityManagerInterface $entityManager)
{
  $repository = $entityManager->getRepository(Budget::class);
  $count = $repository->countBudgets();
  return $this->render("budget/budget.html.twig", ['numberOfBudgets' => $count]);
}

Это работает, но работает только внутри budget/budget.html.twig by usung {{ numberOfBudgets }}.

Как я могу заставить его работать на каждой странице (в частности, я хочу, чтобы он был помещен в мой файл с именем _sidebar.html.twig? Прямо сейчас, если я помещу {{ numberOfBudgets }} на _sidebar.html.twig, я получаю это сообщение об ошибке «Переменная «numberOfBudgets» не существует».

Как мне переписать код?

Какая связь между budget.html.twig и _sidebar.html.twig? Когда и как вы рендерите эту боковую панель? Я бы предположил, что боковая панель не отображается независимо, верно?

yivi 17.03.2022 11:29

@yivi Отображается в начале страницы base.html.twig (сразу после открывающего тега body) с помощью {{ include('_sidebar.html.twig') }}

FreePalestine 17.03.2022 11:36

Тогда что-то не так. Если шаблон был включен именно так, как вы говорите, переменная тоже было бы видно. Из документов: «Включенные шаблоны имеют доступ к переменным активного контекста». (twig.symfony.com/doc/3.x/functions/include.html)

yivi 17.03.2022 11:38

Вам нужно будет включить минимальные примеры веток, которые надежно воспроизводят проблему.

yivi 17.03.2022 11:39

@yivi Я думаю, вы неправильно поняли - или, что более вероятно, я не совсем ясно выразился. Он работает как с базовым файлом, так и с файлом боковой панели, но если я помещаю {{ numberOfBudgets }} на боковую панель и открываю другой URL-адрес, возникает ошибка «Переменная «numberOfBudgets». Возможно, потому, что для переменной задана только страница/URL. Должен ли я тогда использовать глобальные переменные ветки?

FreePalestine 17.03.2022 11:52

Здесь у вас есть несколько вариантов. Как внедрить глобальные переменные во все шаблоны?

yivi 17.03.2022 11:53
Стоит ли изучать 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 и хотите разрабатывать...
1
6
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я бы выбрал переменную сеанса, взгляните на Симфоническая сессия, чтобы получить доступ к вашей переменной count, но обязательно обновите эту переменную в сеансе, если произойдет какое-либо изменение.

public function index(EntityManagerInterface $em) 
{
    $count = $em->getRepository(Budget::class)->countBudgets();

    $session = $this->requestStack->getSession();
    $session->set('budgetCount', $count);
}

Чтобы получить доступ к переменной сеанса в шаблоне ветки, взгляните на Глобальная переменная приложения.

<p>Total budgets: {{ app;session.budgetCount }}</p>

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

yivi 17.03.2022 11:41

Ну, я думал, что сохранение его var в сеансе позволяло ему получить к нему доступ из любого шаблона ветки, что делает его видимым для любого шаблона, нет? (поправьте меня, если я ошибаюсь, это только для понимания!)

Skunka 17.03.2022 14:58
Ответ принят как подходящий

Вы должны использовать глобальную переменную ветки. Переместите Ваш код в сервис:

class BudgetService
{
    public function all(EntityManagerInterface $entityManager)
    {
        $repository = $entityManager->getRepository(Budget::class);
        return $repository->countBudgets();
    }
}

Затем зарегистрируйте глобальную переменную в конфигурации ветки (config/packages/twig.yaml):

twig:
  globals:
    budget: '@App\Services\BudgetService'

Затем вы можете использовать его в любом шаблоне, например:

Total: {{ budget.all }}

Не downvoter, но я боюсь, что это не очень актуально здесь. Вопрос не в «глобальных переменных ветки», а просто в проблеме видимости среди включенных шаблонов (что-то, что вообще не требует создания глобальной переменной)

yivi 17.03.2022 11:42

И если вопрос был о создании глобальных переменных ветки, есть масса дубликатов на выбор :)

yivi 17.03.2022 11:43

Иногда люди не знают, что существуют глобальные переменные ветки :)

Bogdan Kuštan 17.03.2022 11:47

@BogdanKuštan Привет, Богдан! Спасибо за пример. Это работает - почти - я получаю следующую ошибку, и как ее решить? Too few arguments to function App\Service\BudgetService::all(), 0 passed in \budget\vendor\twig\twig\src\Extension\CoreExtension.php on line 1599 and exactly 1 expected - Я понимаю ошибку, но как ее исправить? Как я могу пропустить аргумент во всех ()?

FreePalestine 18.03.2022 10:12

@FreePalestine Я бы использовал внедрение конструктора и внедрил EntityManager (или, что еще лучше, непосредственно BudgetRepository) в __construct(EntityManagerInterface $entityManager), а затем присвоил его некоторой частной переменной ($this->entityManager = $entityManager).

Bogdan Kuštan 18.03.2022 10:19

@BogdanKuštan Спасибо - я очень ценю помощь. Я исправил это, внедрив BudgetRepository напрямую :-)))

FreePalestine 18.03.2022 10:42

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