Laravel和在开发中的视图缓存 - 无法立即看到更改
Laravel和在开发中的视图缓存 - 无法立即看到更改
我和几个朋友决定开始做一个项目,我们了解到Laravel可能是个不错的工具。我们开始在本地使用它开发一些页面,但发现了一些奇怪的问题。
当我们用不同的信息更新一个视图时,视图的信息要过大约5到10分钟才会改变。就像Laravel对视图进行了缓存并设置了过期时间。
我知道这不是我在本地Web服务器上做的任何事情,因为我使用过其他框架,从未遇到过这个问题。
在互联网上搜索后,我找不到一个很好的答案来禁用这个功能。我想使用Laravel,但如果每次我想要做出更改时,视图都要花很长时间才能更新,那它就毫无价值。实际上,这听起来是相反效果。
有没有办法禁用这个功能?为什么我的视图在刚开始使用时要花很长时间才能更新?
在开发中使用Laravel和视图缓存时,可能无法立即看到更改的原因是因为PHP 5.5的行为。这可能会让人感到困惑,因为我从5.3升级到了PHP版本,从来没有遇到过这个问题。
解决方法是在.ini文件中调整OPcache设置。对我来说,这些设置从.ini文件的第1087行开始,看起来像这样:
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1
特别注意opcache.revalidate_freq=60。这实际上是使视图缓存的原因。如果不希望出现这种行为,请将值设置为0,这样每次进行更改时视图都会更新。耶!
编辑于2014年8月21日:
如Matt在下面提到的,确保在更改.ini文件后重新启动Web服务器以使更改生效。
对一些人来说,这可能是显而易见的,但请确保重新启动Web服务器(例如apache或您正在使用的任何其他服务器)。否则,更改将不会生效。
关于为什么在PHP 5.4上会发生这种情况,我不确定。您可以尝试在#laravel IRC中提问。我不确定5.4是否具有OPcache设置。
在开发过程中,当我们使用Laravel和视图缓存时,可能会遇到无法立即看到更改的问题。这个问题的原因可能与Laravel、Apache或PHP无关,也不一定是缓存问题。如果我们将文件共享到像Vagrant这样的虚拟机中,确保编辑器在写入文件时没有使用“原子保存”。
为了测试这个问题,可以使用几个不同的文本编辑器来对观察的文件进行小的编辑(修改一个字符)。使用实现了原子保存的编辑器保存的更改可能不会被虚拟机的文件系统注意到。
我在Mac上使用Sublime Text 3进行编辑,将文件保存到一个通过NFS挂载到Vagrant虚拟机的文件夹中。通过Gulp在本地文件系统上监视文件的变化,并在文件更改时从Vagrant主机请求livereload刷新。
使用Sublime Text 3的默认atomic_save: true
设置,只要改变一个字符就会触发更新,但不会提供更新后的文件。在Vim、TextEdit、Sublime Text 2和TextWrangler中进行编辑都会触发更新并提供更新后的文件内容。将atomic_save: false
切换到Sublime Text 3与其他编辑器保持一致,触发更新并提供正确的文件。
Sublime Text 3的默认首选项中包含以下注释:
// Save via writing to an alternate file, and then renaming it over the
// original file.
"atomic_save": true,
问题可能与更改被写入未被监视的临时文件,然后该临时文件替换我们正在监视的文件有关。修改发生在临时文件被写入时,而不是当它替换我们正在监视的文件时,因此不会触发更新。或者与NFS缓存或VirtualBox的NFS网关有关--中间有很多的东西。
在发现这只是一个编辑器设置之前,浪费了很多时间来调整opcache,Apache模块和Laravel的hack方法。
Laravel和视图缓存在开发过程中无法立即看到更改的原因是由于较新版本的PHP不支持opcache。为了解决这个问题,可以在应用的app/filters.php文件中添加以下代码:
App::before(function($request) { // Clear view cache in sandbox (only) with every request if (App::environment() == 'sandbox') { $cachedViewsDirectory=app('path.storage').'/views/'; $files = glob($cachedViewsDirectory.'*'); foreach($files as $file) { if(is_file($file)) { ($file); } } } });
然而,在Laravel 5.2中,没有app/filters.php文件。那么你应该把这段代码放在哪里呢?