【问题标题】:In CakePHP, how do I call an AppController method from a helper?在 CakePHP 中,如何从助手调用 AppController 方法?
【发布时间】:2014-02-01 23:30:58
【问题描述】:

跟进问题至:In CakePHP, where would I put a method that performs a check on the Session User?


背景:在我之前的问题中,我被告知正确放置方法的位置,例如levelCheck(),它对用户的级别执行半复杂的评估,并且在实际中需要我所有的控制器都是AppController

现在,这种方法对于我设计菜单布局和其他视图设备的方式也非常有用。出于这个原因,我想创建一个可以使用该方法的助手。

问题:我认识到从视图中调用控制器方法通常是不受欢迎的......但是我没有可行的方法来传递数据以复制此方法的功能,也没有我想在两个地方复制该方法吗(违反 DRY 方法)。

问题:我如何从帮助程序中调用此方法,或者是否有更好的方法在视图/元素中提供此方法的使用?

【问题讨论】:

  • 虽然在 cake 2.x 中有点早,但你可以考虑 trait 与你的 levelCheck 逻辑。如果你有 PHP 5.4.x。只需将特征放入/Lib 并调用App::uses('LevelCheckTrait', 'Lib'); 并在控制器/助手中写入use LevelCheckTrait

标签: cakephp cakephp-2.0


【解决方案1】:

将方法放在 AppController 中,同时 - 设置一个将保存结果的变量。

beforeRender 回调中,将结果设置为viewVar。

一些代码:

// AppController

class AppController extends Controller 
{

  $levelCheckResult = null;

  function levelCheck(){
    $this->levelCheckResult = true/false;
  }


  function beforeRender(){
    $this->set('levelCheckResult', $this->levelCheckResult);
  }
}

就是这样,现在您可以在视图中访问它了。

编辑


在 app_controller 中创建一个公共函数,并在 beforeRender() 中将 app_controller 本身发送到视图。

class AppController extends Controller 
{

  function levelCheck(){
    ....
  }


  function beforeRender(){
    $this->set('TheApp', $this);
  }
}
// in the view
$TheApp::levelCheck();

但是,请重新考虑设计。这种操作强烈建议你应该在那里改变一些东西。

简而言之 - 视图仍然是程序的后端执行,而不是客户端,所以在定义上 - 它应该并且可以从控制器控制......

【讨论】:

  • 正如我在问题中提到的,没有办法传递足以提供我在方法本身中获得的灵活性的数据。我基本上可以检查一大堆可能的场景,看看用户是否符合条件。确切的细节对问题的范围并没有真正的帮助,但只是明白我无法传递足以代表我可以用该方法测试的范围的数据......所以我需要实际的方法.
  • @xtraorange 您所描述的(您的视图应该连接到数据库)只能表明您做错了什么。在 MVC 中 - 视图使用的逻辑是基本的,并且应该 - 最多 - 用于控制流或聚合。
  • 逻辑只是指示用户是否应该具有访问权限。我不认为它“如何”确定与讨论真正相关。如果有帮助,请将其视为检查用户是否为管理员......但认识到它需要一个自定义函数才能做到这一点(而不是直接阅读会话)......这大致是该方法的目的,只是检查比管理员更多的可能性。这说明清楚了吗?
  • 我还是不明白为什么要在视图中调用它。该视图仅用于呈现已经处理的数据。 控制器完成后执行视图,这是 mvc 执行的自然顺序 ## 使用我的方式将设置一个变量(它可以是具有任何类型信息的对象..)与任何事物相比。 ## 请注意,通过添加beforeRender 调用,将确保每次都会设置变量。
  • 我了解 MVC 的顺序,但并非所有内容都整齐地落入 MVC 模式;这根本不是它的工作原理,我相信你知道这一点。诸如菜单之类的东西,我正在根据该方法的结果为各种检查创建链接……或者我可能根据使用该方法的检查添加或删除的任何其他元素。再一次(我非常有信心,所以请相信我并考虑其他解决方案),变量不可能包含方法可以检查的许多可能的维度。
【解决方案2】:

我最终使用的解决方案是将方法移动到组件 (CurrentUserComponent)。

从那里开始,就像在我的助手头部调用组件一样简单......

App::uses('CurrentUserComponent', 'Controller/Component');

并引用组件的静态方法:

CurrentUserComponent::levelCheck(x,y,z);

我不认为这完全符合 MVC 模式的意图,但它不会严重扭曲它,并允许从应用程序的任何位置访问该方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 2010-12-25
    • 2016-09-06
    • 1970-01-01
    相关资源
    最近更新 更多