【问题标题】:Caching plugin and normal controllers with duplicate names缓存插件和具有重复名称的普通控制器
【发布时间】:2011-12-27 17:07:31
【问题描述】:

我遇到了与 Cake 2.0 中的缓存、插件和重复模型名称有关的问题。我的应用程序有几个控制器只包含供公众使用的操作(视图、索引和等效项)。数据由作为插件添加的 CMS 管理,插件控制器的某些名称相同。

例如,我的应用程序中有一个 PostsController,插件有一个 PostsController。根据手册,插件控制器扩展PluginAppController,公共控制器扩展AppController。一旦启动缓存(通过将debug 设置为0),问题就开始了。 Cake 尝试访问控制器中不存在的 add 操作,该操作扩展了 AppController,公共应用程序尝试访问来自 PluginAppController 的方法。

我不明白为什么 Cake 会这样做,它会产生各种错误(空白页面、丢失的会话),这些错误也没有被正确记录。当应用程序仍然在 Cake 1.3 和 2.0 生产模式下运行时,一切都运行良好。

/tmp/cache/persistent/ 目录中的文件 cake_core_file_map 似乎是导致问题的原因。一旦我删除它并重新加载任何一个视图,它就会正确呈现。所以程序如下:

  • 加载http://www.example.com/admin/posts成功;
  • 加载http://www.example.com/posts(渲染失败);
  • 清除缓存(或只是 cake_core_file_map);
  • 加载http://www.example.com/posts成功;
  • 加载http://www.example.com/admin/posts(现在无法正确加载)。

我的猜测是 Cake 无法在 cake_core_file_map 中保存对插件和主应用程序路径的正确引用,但我不知道如何强制 Cake 在这方面表现得很好。

有人知道如何阻止 Cake 将插件的控制器与其他名称重复的控制器混淆吗?

编辑

这个问题可能与 Cake 中的一个错误有关,因为 this report 提到了类似的问题,cake_core_file_map 也提到了类似的问题。不幸的是,提到的修复 here 不起作用。

编辑 2 确实有一些自定义路由正在进行,这在 Cake 1.3 中正常工作。这是来自routes.php

Router::connect('/plugin_name', array('plugin' => 'plugin_name', 'controller' => 'users', 'action' => 'login'));
Router::connect('/admin/*', array('plugin' => 'plugin_name', 'controller' => 'posts', 'action' => 'index'));

【问题讨论】:

    标签: cakephp caching cakephp-2.0


    【解决方案1】:

    为插件覆盖 Cake 的标准缓存文件名以使缓存引擎将其单独保存可能会有所帮助。 加载插件时在主引导文件中:

    CakePlugin::loadAll(array('Plugin' => array('bootstrap' => true));
    

    在插件目录中 /app/Plugin/Plugin/Config/bootstrap.php

    <?php
    Cache::config('_cake_core_', array(
        'engine' => 'File',
        'prefix' => 'cake_core_plugin_',
        'path' => CACHE . 'persistent' . DS,
        'serialize' => true,
        'duration' => '+999 days',
    ));
    ?>
    

    【讨论】:

    • 这是 CakePHP 2.* 的正确答案。这篇文章是 6 年前的,但它仍然拯救了一天!
    【解决方案2】:

    主应用和插件之间是否存在冲突路由?听起来您可能需要在主应用程序中为 /posts 和 /admin/posts 创建另一个路由。这应该覆盖来自插件的路由,从而导致任何冲突。当然,在尝试更改之前清除缓存。

    //main app posts route
    Router::connect(
        '/posts',
        array(
            'controller' => 'Posts'
            'action' => 'index'
        )
    );
    
    //plugin posts route
    Router::connect(
        '/admin/posts',
        array(
            'controller' => 'Posts'
            'action' => 'index',
            'plugin' => 'CmsPlugin'
        )
    );
    

    【讨论】:

    • 我已经用我的 routes.php 中的相关条目更新了我的问题。这看起来有顺序吗?
    • 您列出的路由都指向插件(因此数组中的插件键)。但是,您的问题指出,一条路由应指向插件的 Post 控制器,而另一条路由应指向应用程序的 Posts 控制器。插件是否也命名为 Posts - 所以有两个控制器和一个名为 Posts 的插件?
    • 另外,请记住控制器命名约定随着 CakePHP 2.0 的变化。您需要确保正确地大写控制器名称。
    • 插件中有一个名为 Posts 的控制器,应用程序中有一个。该插件有一个不同的名称(比如说cms)。发布的路线只是我的插件路线,还有其他三条路线(两条与 RSS 提要相关,一条将地图控制器连接到 Cake 的家)。对 admin/* 的任何请求都应重新路由到 CMS 插件。
    【解决方案3】:

    事实证明这是一个已知问题(不会让它变得不那么烦人),并且只会在下一个主要版本中修复,根据this Cake bug report

    PHP 5.2 没有命名空间支持,显然 Cake 需要命名空间来支持重复的类名。 PHP 5.3 支持命名空间,Cake 3.0 将需要该版本。

    【讨论】:

    • 这并不完全是 CakePHP 的错误,而更多的是对 PHP 5.2 的不当使用。它在 CakePHP 3 中可用的唯一原因是它需要支持命名空间的 PHP 5.3。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-08
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 2018-12-20
    • 2021-10-02
    • 2015-03-12
    相关资源
    最近更新 更多