【发布时间】:2010-06-24 16:05:03
【问题描述】:
有时我会在本地实施更改并且它们工作正常,我将它们复制到我的远程网络服务器并且更改被忽略。 (代码相同。)
我进入core.php,把debug改成3,再检查一下……可以了!
我感觉这与缓存有关,但我不知道具体要更改什么。
【问题讨论】:
标签: cakephp
有时我会在本地实施更改并且它们工作正常,我将它们复制到我的远程网络服务器并且更改被忽略。 (代码相同。)
我进入core.php,把debug改成3,再检查一下……可以了!
我感觉这与缓存有关,但我不知道具体要更改什么。
【问题讨论】:
标签: cakephp
CakePHP 有一个位于/app/tmp/cache 的缓存。目录结构如下:
# /app/tmp/cache
# /app/tmp/cache/models
# /app/tmp/cache/persistent
# /app/tmp/cache/views
通常遇到的主要问题是模型缓存。当调试关闭(即在生产中)并且您使 CakePHP 调度时,它会内省所有数据库表的模式并将它们存储在上面models 文件夹中的平面文件中。如果您不删除此文件夹中的文件,CakePHP 会开始说模型/表/字段不存在,而它们在您的数据库中明确存在。
如果您在应用程序中启用视图缓存,当第一次呈现视图时,CakePHP 会将平面文件编译到 views 文件夹,以防止在下一次请求时必须再次呈现这些视图。
在 CakePHP 的引导过程中,它必须确定您在安装中使用的目录结构,然后才能访问重要文件(如 database.php)。因此,CakePHP 将生成缓存文件到persistent 目录,其中包含每个重要目录和文件、您正在使用的任何插件甚至您创建的任何本地化的绝对路径,因此它可以快速在语言之间翻译您的应用程序而无需重新解析.pot 文件。
因此,简单地说,当您对生产中的应用程序进行代码更改时,您必须记住删除这些目录中的所有文件,或者将其添加为您的deployment mechanism 的一部分。但是,您不得删除任何目录。
将 debug 更改为 3 对您有效的原因是,当调试模式打开时(任何大于零的值),缓存会在每次请求时被清除并重新生成,但是 - 虽然这有效 - 自动化并不容易。
有多种以编程方式执行此操作的方法 - 包括 shell commands、CakePHP plugins、Capistrano configs、Ant 文件 - 但也可以手动执行此操作。
【讨论】:
Configure::write('Cache.disable', true); 对没有缓存很有用。
我找到了很好的解决方案here。我认为它应该是完美的并且工作正常。解决方法如下:
function _clear_cache()
{
Cache::clear();
clearCache();
$files = array();
$files = array_merge($files, glob(CACHE . '*')); // remove cached css
$files = array_merge($files, glob(CACHE . 'css' . DS . '*')); // remove cached css
$files = array_merge($files, glob(CACHE . 'js' . DS . '*')); // remove cached js
$files = array_merge($files, glob(CACHE . 'models' . DS . '*')); // remove cached models
$files = array_merge($files, glob(CACHE . 'persistent' . DS . '*')); // remove cached persistent
foreach ($files as $f) {
if (is_file($f)) {
try {
@unlink($f);
} catch (Exception $ex) {
$files['errors'][] = $ex->getMessage();
}
}
}
if (function_exists('apc_clear_cache')):
apc_clear_cache();
apc_clear_cache('user');
endif;
return $files;
}
只需在您的 appcontroller 中使用上述函数,然后在您想要清除所有缓存的位置运行该函数。
【讨论】:
您可能会发现这对于在 CakePHP 1.2、1.3 中清除缓存很有用,我认为这在 2.x 中也可以使用(稍作修改以使用新的 CakeRequest 类):
if(Configure::read('debug') > 0 and isset($this->params['url']['emptycache'])) {
// clear Cache::write() items
Cache::clear();
// clear core cache
$cachePaths = array('views', 'persistent', 'models');
foreach($cachePaths as $config) {
clearCache(null, $config);
}
$this->Session->setFlash('Cache cleared', 'default', array(), 'info');
}
将此添加到您的 AppController::beforeFilter() 中。
基本上,当您处于开发模式时,上述代码可让您通过将查询字符串附加到 URL 来轻松清除缓存,例如mydomain.com/?emptycache - 它将删除 Cake 的所有缓存文件。
【讨论】:
clearCache(null, 'models'); 似乎没有工作(蛋糕正在剥离将查询发送到 mysql 之前的新列)。修复可能会将其拆分为来自 shell 的 2 个调用,以便在第二次运行时更新缓存。 (蛋糕 1.3)
这绝对是缓存。在服务器端,如果您启用了缓存,请不要怀疑是否发生了缓存。您可以在 core.php 中将其关闭,或者更可能在升级应用程序时清除缓存 Cache::clear()。在客户端,您可能需要调整浏览器以完全禁用缓存。
【讨论】:
我认为这是一个客户端问题。您是否安装了 Firefox Mozilla 的 Web Developer addon?如果是,您可以轻松地在客户端停用缓存以进行检查。
如果您更改调试级别,它会再次起作用,因为 url 和 cookie 数据可能略有不同,导致从服务器重新加载。如果还是不行那就肯定是服务端缓存了……
注意:除此之外,您还可以使用该插件为 Web 开发做各种有用的事情,例如动态修改 css 或将样式可视化为页面上的叠加层。
【讨论】:
我遇到了同样的问题,deizel,给出了很好的解释,只是想补充一下,如果你不做很多改变,简单的方法,不删除或删除缓存数据,或者类似的东西,是将调试级别从 0 更改为 3,刷新您对 po 文件进行更改的页面,然后再次将调试设置为 0。
【讨论】: