In my main layout there is a piece of code that should receive an array with categories or get this data from the database.
Now I pass them through actionIndex:
$categoriesA = Categories::find()->all();
return $this->render('index', ['categories' => $categories]);
In index.php, I write them into parameters like this:
$this->params['categories'] = $categories;
And already in the main layout, I get this data. But then on other pages the problem arises that this data is not. It is possible to do the same on each page, but this will every time be a query to the database, and somehow it is not very nice to write everywhere. I would like to know if there is an alternative to my decision so that in each action not to access the database and in each view not to write:
$this->params['categories'] = $categories;

    2 answers 2

    You can create your own base controller, and then all your controllers will be inherited not from yii\web\Controller , but from your controller. In the base controller, you can override the constructor, or the beforeAction method in which you can do something before each action. You can also create a field in the base controller, and then write something into it in the beforeAction method or in the constructor. In layout, as in any other view, you can access this field through context

    An example of your base controller

     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); } } 

    Example of accessing the $ categories field from the layout and any view

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

    But keep in yii\web\Controller , your controllers will now have to be inherited from your new app\components\Controller base controller and not from yii\web\Controller

      Create a widget and an index view in it:

       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]) } } 

      Then output this widget to the main layout:

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

      Now, all pages will be updated.