创建可重用控制器

在Yii中,你可以创建可复用的控制器。如果你创建许多应用或者控制器,他们有相同的类型,将所有常用的代码移动到一个可复用的控制器中将会节省很多时间。

在本小节中,我们将会尝试创建一个常用的CleanController,它会清理临时文件夹以及flush缓存数据。

准备

按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的yii2-app-basic应用。

如何做…

执行如下步骤,创建可复用的控制器:

  1. 创建cleaner目录,并添加独立CleanController控制器:
  1. <?php
  2. namespace app\cleaner;
  3. use Yii;
  4. use yii\filters\VerbFilter;
  5. use yii\helpers\FileHelper;
  6. use yii\web\Controller;
  7. class CleanController extends Controller
  8. {
  9. public $assetPaths = ['@app/web/assets'];
  10. public $runtimePaths = ['@runtime'];
  11. public $caches = ['cache'];
  12. public function behaviors()
  13. {
  14. return [
  15. 'verbs' => [
  16. 'class' => VerbFilter::className(),
  17. 'actions' => [
  18. 'assets' => ['post'],
  19. 'runtime' => ['post'],
  20. 'cache' => ['post'],
  21. ],
  22. ],
  23. ];
  24. }
  25. public function actionIndex()
  26. {
  27. return $this->render('@app/cleaner/views/index');
  28. }
  29. public function actionAssets()
  30. {
  31. foreach ((array)$this->assetPaths as $path) {
  32. $this->cleanDir($path);
  33. Yii::$app->session->addFlash(
  34. 'cleaner',
  35. 'Assets path "' . $path . '" is cleaned.'
  36. );
  37. }
  38. return $this->redirect(['index']);
  39. }
  40. public function actionRuntime()
  41. {
  42. foreach ((array)$this->runtimePaths as $path) {
  43. $this->cleanDir($path);
  44. Yii::$app->session->addFlash(
  45. 'cleaner',
  46. 'Runtime path "' . $path . '" is cleaned.'
  47. );
  48. }
  49. return $this->redirect(['index']);
  50. }
  51. public function actionCache()
  52. {
  53. foreach ((array)$this->caches as $cache) {
  54. Yii::$app->get($cache)->flush();
  55. Yii::$app->session->addFlash(
  56. 'cleaner',
  57. 'Cache "' . $cache . '" is cleaned.'
  58. );
  59. }
  60. return $this->redirect(['index']);
  61. }
  62. private function cleanDir($dir)
  63. {
  64. $iterator = new \DirectoryIterator(Yii::getAlias($dir));
  65. foreach($iterator as $sub) {
  66. if(!$sub->isDot() && $sub->isDir()) {
  67. FileHelper::removeDirectory($sub->getPathname());
  68. }
  69. }
  70. }
  71. }
  1. actionIndex方法创建cleaner/views/index.php视图文件:actionIndex
  1. <?php
  2. use yii\helpers\Html;
  3. /* @var $this yii\web\View */
  4. $this->title = 'Cleaner';
  5. $this->params['breadcrumbs'][] = $this->title;
  6. ?>
  7. <div class="clean-index">
  8. <h1><?= Html::encode($this->title) ?></h1>
  9. <?php if (Yii::$app->session->hasFlash('cleaner')): ?>
  10. <?php foreach
  11. ((array)Yii::$app->session->getFlash('cleaner', []) as
  12. $message): ?>
  13. <div class="alert alert-success">
  14. <?= $message ?>
  15. </div>
  16. <?php endforeach; ?>
  17. <?php endif; ?>
  18. <p>
  19. <?= Html::a('Clear Caches', ['cache'], [
  20. 'class' => 'btn btn-primary',
  21. 'data' => [
  22. 'confirm' => 'Are you sure you want to clear all cache data?',
  23. 'method' => 'post',
  24. ],
  25. ]) ?>
  26. <?= Html::a('Clear Assets', ['assets'],
  27. ['class' => 'btn btn-primary',
  28. 'data' => [
  29. 'confirm' => 'Are you sure you want to clear all temporary assets?',
  30. 'method' => 'post',
  31. ],
  32. ]) ?>
  33. <?= Html::a('Clear Runtime', ['runtime'],
  34. ['class' => 'btn btn-primary',
  35. 'data' => [
  36. 'confirm' => 'Are you sure you want to clear all runtime files?',
  37. 'method' => 'post',
  38. ],
  39. ]) ?>
  40. </p>
  41. </div>
  1. 配置config/web.phpcontrollerMap部分,附加控制器到应用中:
  1. $config = [
  2. 'id' => 'basic',
  3. 'basePath' => dirname(__DIR__),
  4. 'bootstrap' => ['log'],
  5. 'controllerMap' => [
  6. 'clean' => 'app\cleaner\CleanController',
  7. ],
  8. 'components' => [
  9. ...
  10. ]
  11. ...
  12. ];
  1. 添加一个新的条目到主菜单中:
  1. echo Nav::widget([
  2. 'options' => ['class' => 'navbar-nav navbar-right'],
  3. 'items' => [
  4. ['label' => 'Home', 'url' => ['/site/index']],
  5. ['label' => 'Cleaner', 'url' => ['/clean/index']],
  6. ['label' => 'About', 'url' => ['/site/about']],
  7. ...
  8. ],
  9. ]);
  1. 打开控制器,并清理assets:

创建可重用控制器 - 图1

  1. 如果你用的是yii2高级应用模板,只需要在配置中指定正确的路径:
  1. 'controllerMap' => [
  2. 'clean' => 'app\cleaner\CleanController',
  3. 'assetPaths' => [
  4. '@backend/web/assets',
  5. '@frontend/web/assets',
  6. ],
  7. 'runtimePaths' => [
  8. '@backend/runtime',
  9. '@frontend/runtime',
  10. '@console/runtime',
  11. ],
  12. ],

现在我们可以附加这个控制器到任何应用中。

工作原理…

当你运行一个应用时,假如路由是clean/index,指向CleanController::actionIndex,Yii检查controllerMap是否定义了。因为这里我们有一个干净的控制器,Yii会执行它,而不是像常用的方式。

在这个控制器中,我们定义了assetPathsruntimePathscaches属性,这能够连接这个控制器到应用的不同路径和缓存结构。当附加这个控制器的时候设置它。

参考