In many frameworks, the concept of a base controller that is being extended by other ones is described right in the guide. In Yii, it is not in the guide, as you can achieve flexibility in many other ways. Still, using a base controller is possible and can be useful.
Let's say we want to add some controllers that will be accessible only when the user is logged in. We can certainly set this constraint for each controller separately, but we will do it in a better way.
Create a new application using the Composer package manager, as described in the official guide at http://www.yiiframework.com/doc-2.0/guide-startinstallation.html.
@app/components/BaseController.php
with the following code:<?php namespace appcomponents; use Yii; use yiiwebController; use yiifiltersAccessControl; class BaseController extends Controller { public function actions() { return [ 'error' => ['class' => 'yiiwebErrorAction'], ]; } public function behaviors() { return [ 'access' => [ 'class' => AccessControl::className(), 'rules' => [ [ 'allow' => true, 'actions' => 'error' ], [ 'allow' => true, 'roles' => ['@'], ], ], ] ]; } }
This controller has an action map with an error action also.
TestController
by Gii, but set the value of the base class field as app/components/BaseController
:You will get something similar to the following:
<?php namespace appcontrollers; class TestController extends appcomponentsBaseController { public function actionIndex() { return $this->render('index'); } }
TestController
will be only accessible if the user is logged in, even though we have not declared it explicitly in the TestController
class. You can check it by visiting http://yii-book.app/index.php?r=test/index
while logged out.The trick is nothing more than a basic class inheritance. If filters or access control rules are not found in TestController
, then they will be called from SecureController
.
If you need to extend the base controller's method, keep in the mind that it must not be overridden. For example, we need to add a page action to the controller's action map:
<?php namespace appcontrollers; use yiihelpersArrayHelper; use appcomponentsBaseController; class TestController extends BaseController { public function actions() { return ArrayHelper::merge(parent::actions(), [ 'page' => [ 'class' => 'yiiwebViewAction', ], ]); } public function behaviors() { $behaviors = parent::behaviors(); $rules = $behaviors['access']['rules']; $rules = ArrayHelper::merge( $rules, [ [ 'allow' => true, 'actions' => ['page'] ] ] ); $behaviors['access']['rules'] = $rules; return $behaviors; } public function actionIndex() { return $this->render('index'); } }
For further information, refer to http://www.yiiframework.com/doc-2.0/yii-base-controller.html.
18.222.67.251