YII2 передача данных в main layout

139
30 августа 2019, 10:20

У меня в main layout есть часть кода которая должна получать массив с категориями или получать эти данные из БД.
Сейчас я их передаю через actionIndex:
$categoriesA = Categories::find()->all();
return $this->render('index', ['categories' => $categories]);
В index.php я их записываю в параметры вот так:
$this->params['categories'] = $categories;
И уже в main layout я получаю эти данные. Но потом на других страничках возникает проблема что этих данных нет. Можно на каждой странице проделать тоже самое, но это каждый раз будет идти запрос к БД, да и как-то не очень красиво так везде писать. Хотелось бы узнать есть ли альтернатива моему решению чтобы в каждом action не обращаться к БД и в каждой вьюшке не писать:
$this->params['categories'] = $categories;

Answer 1

Вы можете создать свой собственный базовый контролер, и затем все ваши контроллеры будут наследоваться уже не от yii\web\Controller, а от вашего контроллера. В базовом контроллере вы можете переопределить конструктор, или метод beforeAction в котором вы сможете что-то выполнять перед каждым action'ом. Так же в базовом контроллере вы можете создать какое-то поле, а затем в него что-то записать в методе beforeAction или же в конструкторе. В layout'е, как и в любом другом view, вы сможете обратиться к этому полю через context

Пример своего базового контроллера

namespace app\components;
use yii\web\Controller as BaseController;
use yii\base\Action;
class Controller extends BaseController
{
    /**
     * @var Category[]|array
     */
    public $categories;

    /**
     * Выполнять перед каждым action'ом
     * @param Action $action
     * @return bool
     * @throws \yii\web\BadRequestHttpException
     */
    public function beforeAction($action)
    {
        // Получить категории
        $this->categories = Categories::find()->all();
        // Вызов базового метода beforeAction
        return parent::beforeAction($action);
    }
}

Пример обращения к полю $categories из layout'а и любого view

<?php
/* @var $this \yii\web\View */
/* @var $controller \app\components\Controller */
$controller = $this->context;
$categories = $controller->categories;

Но учтите, ваши контроллеры теперь должны будут наследоваться именно от вашего нового базового контроллера app\components\Controller а не от yii\web\Controller

Answer 2

Создайте виджет и представление index в нем:

namespace ...\...;
use yii\base\Widget;
class CategoriesWidget extends Widget
{
    public function init()
    {
        parent::init();
    }
    public function run()
    {
        $categoriesA = Categories::find()->all();
        return $this->render('index', ['categories' => $categories])
    }
}

Потом выводите этот виджет в main layout:

<?= CategoriesWidget::::widget() ?>

Теперь, на всех страницах будет обновление.

READ ALSO
Как отпарсить IP и положить в массив

Как отпарсить IP и положить в массив

Есть ответ от оборудования https://pastebincom/VavtUJpz

141
что за ошибка в laravel

что за ошибка в laravel

пытаюсь выполнить любую команду через ssh, например php artisan route:list и выдает такую ошибку

136
Wordpress ошибка ответа сайта 500 при создании functions.php

Wordpress ошибка ответа сайта 500 при создании functions.php

Создаю тему с нуля, все ОК работает, но как только создаю файл functionsphp (пустой) - сайт перестает работать и выдает ошибку 500, даже в панели администратора

121
Не могу добавить данные в БД(MySQL) через PDO

Не могу добавить данные в БД(MySQL) через PDO

Помогите, пожалуйстая новичок, только-только изучаю PHP и не могу добавить данные (которые содержится внутри form) в БД через PDO

127