如何在Yii2的不同文件中分离每个动作

问题描述

我是Yii2框架的新手。为了使Web应用程序具有结构,我想将每个控制器放在一个文件夹中,并为每个子文件夹中的每个动作创建一个单独的控制器。像那个!

controllers
        **User**
            IndexController
            EditController
            UpdateController
        
        **Profile**
            IndexController
            EditController
            UpdateController

如何在Yii2中进行安排。 预先感谢

解决方法

你的例子是对的。

controllers/user/IndexController.php

views/user/index/index.php

然后在IndexController/EditController/UpdateController中拥有actionIndex,如果您运行domain.com/user/indexdomain.com/user/edit,它将在当前控制器中执行actionIndexIndexControllerEditController

domain.com/user/index = domain.com/user/index/index

and 

domain.com/user/edit = domain.com/user/edit/index
,

不确定是否还有其他更有效的方法,但以下一种可行的方法。

注意:此示例假定您使用的是https://github.com/yiisoft/yii2-app-advanced,但它也适用于基本应用程序,只需更改名称空间即可。

所以,假设您说我们有一个控制器,并且我们希望将其某些操作存储到不同的php文件中。

<?php

// frontend\controllers\SiteController.php

namespace frontend\controllers;

use yii\web\Controller;

class SiteController extends Controller {

  public function actions() {
    return [
        'error' => [
            'class' => 'yii\web\ErrorAction',],'captcha' => [
            'class' => 'yii\captcha\CaptchaAction','fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,'hello-world' => [
            'class' => 'frontend\controllers\site\HelloWorldAction',];
  }

  public function actionIndex() {
      // ...
  }

所以您可以看到我们有3个外部动作和1个内部动作。

前两个是用于错误页面和验证码生成的框架工具,实际上它们启发了我的答案。

第三个是我们定义的:

'hello-world' => [
   'class' => 'frontend\controllers\site\HelloWorldAction',

因此,我们已经命名了动作,并在单独的目录中创建了新的动作类。

<?php

// frontend\controllers\site\HelloWorldAction.php

namespace frontend\controllers\site;

use yii\base\Action;

class HelloWorldAction extends Action {

  public function run($planet='Earth') {
    return $this->controller->render('hello-world',[
        'planet'=>$planet,]);
  }

}

最后,我们的观点:

<?php

// frontend\views\site\hello-world.php

/* @var $this yii\web\View */

use yii\helpers\Html;

$this->title = 'Hello world page';
?>

<h1>Hello world!</h1>

<p>We're on planet <?php echo Html::encode($planet); ?></p>

并观察它的作用:

Testing on localhost

更新

发布答案后,我意识到也许您也可以从另一种技术中受益。

如果您只想这样做,那么上一个答案很好:Extract actions into individual files

但是,如果您的应用程序具有一定的大小,也许您应该考虑使用模块

您可以手动创建它们,也可以使用Gii生成它们:

Yii2 module generation

生成后,将其包含在您的配置中

<?php
    ......
    'modules' => [
        'profile' => [
            'class' => 'frontend\modules\profile\Module',......

模块正是这样做的,将应用程序逻辑分为一个目录,控制器,模型,视图,组件等。

另外两个提示:

现在要访问您的模块,只需访问http://www.your-site.local/profile/default/index,就像您看到的那样,它就像module/controller/action

如果要生成模块内部动作的链接,则可以执行以下操作:

<?php
echo Url::to([
    'profile/default/index','param'=>'value',]);
?>

同样,如您所见,我们使用module/controller/action作为路线。

最后,如果您位于某个模块中,例如profile/picture/edit,并且想要从SiteController链接到“联系人”页面,则可以这样做:

<?php
echo Url::to([
    '//site/contact',]);
?>

请注意,在路径的开头使用双斜杠//。如果没有它,它将生成当前模块profile/site/contact的网址。