【问题标题】:Yii, how to have controller code that runs in all viewsYii,如何让控制器代码在所有视图中运行
【发布时间】:2013-05-17 15:06:19
【问题描述】:

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

有没有办法让控制器和动作始终被任何视图(不是部分视图)调用,而不是修改所有控制器和所有动作并添加代码的 sn-ps?

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

以下是其中一个视图的操作方法之一

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));

}

【问题讨论】:

  • 如果您需要重复控制器逻辑,它一开始就不应该存在。您可以创建一个服务类来处理共享逻辑。
  • 好的@Bart 谢谢你,在设置服务类来处理共享逻辑方面有什么建议吗?

标签: php yii


【解决方案1】:

是的,可以使用布局和基本控制器。

如果你来自 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;
  }
}

【讨论】:

  • 我不知道组件控制器,这很好!但是@Jorge 在控制器中输入该代码会返回一个解析错误,因为它似乎只接受变量中的字符串和数组
  • 它不是一个组件,它在组件文件夹中大声笑。您可以创建一个名为 base_controllers 的文件夹并将其设置为在 config/main.php 中自动加载
  • 我更新了我的答案,忘记了在对象实例化时对象的属性必须是常量,将其移至函数。
【解决方案2】:

正如评论中所说,将重复的逻辑放在控制器中是不好的。记住 MVC 逻辑 - thick model、wise view 和 thin controller。为了显示登录的用户数据,我建议创建一个小部件。您可以将该小部件放置在您的布局或任何视图中。

最简单的是

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');

更多信息见docs on Yii widgets

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多