2014-10-28 81 views
0

对于每个请求,我必须加载或至少创建一个MyUser的实例,其中包含用户名,一些内部权限信息,指向头像的链接等等。Yii 1.1:跨控制器变量(甚至是跨视图变量)

事情是,我需要为每个控制器和大多数视图(根据用户状态和权限呈现或不呈现某些控件)需要此信息。

听起来好像需要一个全局变量,在请求被处理时创建。解决这个问题的最好方法是什么?

+0

我不熟悉警予DI实现,但你肯定可以实例(或注射)MYUSER我n基础控制器的构造函数,并将其传递给您的视图。 – Steve 2014-10-28 13:32:06

+0

@Steve这就是要点 - 你总是需要注入一些东西,你基本上需要到处都是。是的,它打破了DI的原则,但它是什么...它使开发更容易,你无法测试视图! – 2014-10-28 13:33:56

+1

那么如果你在基础控制器中创建(或注入)并将其设置为公共属性('// constructor $ this-> somePublicProp = $ user;'),那么你可以在每个视图中使用'$ this-> somePublicProp ;'所以你甚至不需要在继承的控制器中键入User,它会自动传递 – Steve 2014-10-28 13:56:46

回答

2

覆盖CWebUser(这是您在使用您的自定义类WebUser(放置在组件或其他类文件夹自动包含的类)中的Yii :: app() - > user)时调用的,并定义了一些getter

<?php 
class WebUser extends CWebUser { 
    private $_model = null; 
    function getRole() { 
     if($user = $this->getModel()){ 
      return $user->userRole->name; 
     } 
    } 
    private function getModel(){ 
     if (!$this->isGuest && $this->_model === null){ 
      $this->_model = User::model()->findByPk($this->id); 
     } 
     return $this->_model; 
    } 
} 

如果用户自定义类,而不是CWebUser,你必须明确地告诉应用程序的配置要使用的类:

'user'=>array(
    'class' => 'WebUser', 
    // … 
), 
+0

这是Yii1的答案。请列出您要求帮助的Yii版本。 – tebazil 2014-10-28 13:37:28

+0

是的,谈到1.1 – 2014-10-28 13:40:01

2

您可以创建它与getRole()下面的例子做(或注入)公司的一个实例MyUser你的基地控制器的nstructor,并将其设置为一个公共属性:

//i am not familiar with Yii naming conventions, so ignore class name etc 

class BaseController 
{ 
    public $user; 
    //presuming you can inject, if not $user = new MyUser(); 
    function __construct(MyUser $user){ 
     $this->user = $user; 
    } 
} 

然后继承BaseController可以访问,如果他们需要的所有控制器:

class HomeController extends BaseController 
{ 
    function someAction(){ 
     $name = $this->user->name; 
    } 

} 

而且无论动作是否访问实例,其在所有视图中使用,而不作为参数传递给渲染:

//someview 
echo $this->user->name; 
+0

我建议不要这样做。这是一个肮脏的技巧 - yii已经有了我们在应用程序中使用的某种容器Yii :: app()和用户组件Yii :: app() - >用户的快捷方式。通过在控制器中声明另一个用户引用,您违背常识 - 您正在创建另一个快捷方式。有什么意义?另外,afaik Yii1没有DI,所以你不能在这里注入。 – tebazil 2014-10-28 15:35:11

+0

@tebazil是的,正如我在评论中所说的,我对Yii不是特别熟悉,并且希望我的回答不是OP得到的最好结果。至于'为什么打扰',我相信OP在每次操作中必须通过渲染方法传递用户而感到沮丧 - 如果有更好的方式将数据传递给每个视图,而不必在每个控制器操作中明确这样做,那么确定OP会很高兴知道这件事。也许在视图中直接访问'Yii:app()'是可以接受的吗?或者你可以以某种方式在控制器的构造函数中将数据推入视图? – Steve 2014-10-28 16:07:45

+0

在视图中使用Yii:app()非常好,它在官方的yii示例应用程序中以这种方式使用。这是一个应用程序范围的服务定位器。您经常会用模板来检查Yii :: app() - > user-> isGuest,以检查用户是否已登录。 – tebazil 2014-10-28 16:20:44