如何让控制器代码在所有视图中运行


Yii, how to have controller code that runs in all views

我想知道是否有一种理想的方法可以在每个视图文件中运行相同的代码。

而不是修改所有的控制器和所有的动作和添加代码片段,有一种方法,有一个控制器和动作,总是由任何视图调用(不是部分视图)?

我需要在所有视图的代码,获得当前登录的用户,并获得在其他相关表中的数据。

以下是其中一个视图

的操作方法之一
public function actionIndex()
{
    // the following line should be included for every single view
    $user_profile = YumUser::model()->findByPk(Yii::app()->user->id)->profile;
    $this->layout = 'column2';
    $this->render('index', array('user_profile' => $user_profile));
}

是的,这是可能的,使用布局和基础控制器。

如果您来自Yii代码生成器,那么在components文件夹中应该有一个Controller类。

如果你的控制器是ExampleController extends Controller而不是CController

Controller中你可以分配:

public function getUserProfile() {
  return YumUser::model()->findByPk(Yii::app()->user->id)->profile;
}

在你的布局文件中:

<?php echo CHtml::encode($this->getUserProfile()); ?>

因为$this指向控制器,而控制器继承了名为$user_profile的属性。

但是,您应该在登录到会话时分配profile和其他不会随setState变化的东西。这样你就可以这样做:

 <p class="nav navbar-text">Welcome, <i><?php echo Yii::app()->User->name; ?></i></p>

在MySQLUserIdentity中设置状态的例子(由我完成)

class MySqlUserIdentity extends CUserIdentity
{
  private $_id;
  public function authenticate()
  {
    $user = User::model()->findByAttributes( array( 'username' => $this->username ) );
    if( $user === null )
      $this->errorCode = self::ERROR_USERNAME_INVALID;
    else if( $user->password !== md5( $this->password ) )
      $this->errorCode = self::ERROR_PASSWORD_INVALID;
    else
    {
      $this->_id = $user->id;
      $this->setState( 'username', $user->username );
      $this->setState( 'name', $user->name );
      $this->setState( 'surname', $user->surname );
      $this->setState( 'email', $user->email );
      $this->errorCode = self::ERROR_NONE;
    }
    return !$this->errorCode;
  }
  public function getId()
  {
    return $this->_id;
  }
}

正如在评论中发布的那样,在控制器中放置重复的逻辑是不好的。记住MVC逻辑——厚模型,智能视图和瘦控制器。为了显示登录的用户数据,我建议创建一个小部件。然后你可以把这个小部件放在你的布局中,或者在任何视图中。

最简单的是

class MyWidget extends CWidget
{
    private $userData = null;
    public function init()
    {
        $this->userData = YumUser::model()->findByPk(Yii::app()->user->id)->profile;
        // Do any init things here
    }
    public function run()
    {
        return $this->render('viewName', array('user_profile' => $userData));
    }
}

然后在任何视图(或布局,实际上也是视图)你可以使用它:

$this->widget('path.to.widget.MyWidget');

更多信息请参见Yii widgets文档