Выполнить мой код перед любым действием любого контроллера

Я хотел бы проверить, заполнил ли мой пользователь определенные поля в своем профиле, прежде чем он сможет получить доступ к любому действию любого контроллера. Например

if(empty(field1) && empty(field2))
{
   header("Location:/site/error")
}

В yii1 я мог бы сделать это в protected\components\Controller.php в функции init(), но в yii2 я не уверен, куда поместить свой код. Я не могу изменять основные файлы, но не знаю, что делать в бэкэнде моего расширенного приложения, чтобы оно заработало.

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


person Misko Mali    schedule 27.11.2014    source источник


Ответы (4)


Если вам нужно выполнить код перед каждым контроллером и действием, вы можете сделать следующее:

1 — добавьте компонент в каталог компонентов, например (MyGlobalClass):

namespace app\components;
class MyGlobalClass extends \yii\base\Component{
    public function init() {
        echo "Hi";
        parent::init();
    }
}

2 — добавьте компонент MyGlobalClass в массив компонентов в файле конфигурации:

'components' => [
    'MyGlobalClass'=>[
        'class'=>'app\components\MyGlobalClass'
     ],
     //other components

3 — добавить MyGlobalClass в массив bootstarp в файле конфигурации:

'bootstrap' => ['log','MyGlobalClass'],

Теперь вы можете видеть Hi перед каждым действием.

Обратите внимание, что если вам не нужно использовать Events и Behaviors, вы можете использовать \yii\base\Object вместо \yii\base\Component

person Ali MasudianPour    schedule 27.11.2014
comment
@MiskoMali Используете ли вы модули? - person Ali MasudianPour; 28.11.2014
comment
Другое дело, нужно ли взаимодействовать с формами? или вам нужно просто выполнить какой-то код перед каждым действием контроллера? в случае форм, если вы используете модель, вы можете использовать beforeValidate() - person Ali MasudianPour; 28.11.2014
comment
@MiskoMali Что ж, если вы используете модуль, вы можете написать свой код в методе init(), который будет выполняться перед каждым контроллером этого модуля. - person Ali MasudianPour; 28.11.2014
comment
Мне просто нужно выполнить некоторый код перед каждым действием, не связанным с какими-либо формами или базой данных. Я использую модули в папке поставщика, а не в бэкэнд-папке. В бэкэнд-папке я использую только контроллер и модели. - person Misko Mali; 28.11.2014
comment
Мне придется попробовать это самому :), я понятия не имею, как это будет работать, поскольку я не вижу связи между вашим MyGlobalClass и контроллером. Не следует ли использовать MyGlobalClass вместо \yii\base\Component ? - person Mihai P.; 28.11.2014
comment
@МихайП. Нет, дорогой, это просто класс (компонент, объект, событие или поведение), который будет инициирован при начальной загрузке приложения. Как только приложение запустится, будет вызван метод init() этого класса. - person Ali MasudianPour; 28.11.2014
comment
Вы правы, я как-то об этом не подумал :). - person Mihai P.; 28.11.2014
comment
Честно говоря, то, что он хочет сделать, довольно безумно, он не сможет войти в систему, потому что у него не будет доступа ни к какому контроллеру/действию. - person Mihai P.; 28.11.2014
comment
я пробовал это, я делаю спокойное приложение, и мне нужно, чтобы все ответы возвращались в формате json (сейчас по какой-то причине все ответы в xml), я просто выполняю команду, чтобы изменить формат ответа, но это не так Работа - person Oscar Reyes; 11.11.2015
comment
Также работает, если ваш класс расширяет BaseObject. У меня это работает в бэкэнде расширенного шаблона, чтобы обеспечить запуск date_default_timezone_set для всех действий во всех контроллерах. Во фронтенде .htaccess заставляет все проходить через actionIndex, так что там было проще. - person Rich Harding; 19.04.2018

Просто добавьте файл конфигурации в массив $config:

    'on beforeAction' => function ($event) {
           echo "Hello";
    },
person Ruslan Novikov    schedule 10.03.2015
comment
Это лучше всего подходит для обработки «глобального» события beforeAction. - person leealex; 18.10.2017
comment
да, это очень хорошо, и я думаю, что это был бы лучший ответ! - person kiamoz; 05.01.2018

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

'on beforeAction' => function ($event) {
      // To log all request information
},
'components' => [
    'response' => [
        'on beforeSend' => function($event) {
            // To log all response information
        },
    ],
];
person Sajjad Dehghani    schedule 17.11.2018

Или https://github.com/yiisoft/yii2/blob/master/docs/guide/security-authorization.md использовать RBAC, чтобы ограничить доступ к действиям контроллера по одному на основе правил. Почему вы хотите ограничить доступ к действиям контроллера на основе пользовательских полей, мне не понятно. Вы не сможете получить доступ ни к чему (включая форму входа), если вы установите там ограничение.

person Mihai P.    schedule 28.11.2014