关于php:Laravel和开发中的视图缓存-无法立即看到更改

Laravel and view caching in development — can't see changes right away

我和一些朋友决定开始一个项目,我们遇到了Laravel,并认为这可能是一个很好的工具。 我们开始在本地使用它来开发我们的某些页面,并发现了一些奇怪的地方。

当我们使用其他信息更新视图时,将需要大约5到10分钟才能更改视图信息。 就像Laravel正在缓存视图并在其上放置TTL一样。

我知道这不是我在本地Web服务器上所做的任何事情,因为我使用了其他框架,而且从未遇到过此问题。

搜索互联网后,我找不到如何禁用此功能的好答案。 我想使用Laravel,但是如果每次更改时我的视图都需要花费一些时间来更新,那将毫无用处。 实际上,这听起来适得其反。

有什么办法可以禁用此功能? 为什么我的观点永远需要立即更新?


#laravel IRC频道是上帝发送的。这完全与Laravel的行为无关。这实际上是PHP 5.5所做的事情。

之所以感到莫名其妙,是因为我从5.3升级了PHP版本,却再也没有这个问题。

在您的.ini文件中,您需要调整OPcache设置。对我来说,这些设置从.ini文件的1087行开始,看起来像这样:

1
2
3
4
5
6
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服务器以使更改生效。


对于较新版本的PHP,opcache不起作用。这是我使用的(在app / filters.php中):

1
2
3
4
5
6
7
8
9
10
11
12
13
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)) {
                @unlink($file);
            }
        }
    }
});


可能这根本不是缓存问题,并且与Laravel,Apache或PHP无关。如果要将文件共享到Vagrant之类的虚拟机中,请确保编辑器在写入文件时未使用"原子保存"。

要对此进行测试,请使用几个不同的文本编辑器对监视的文件进行小的编辑(单个字符)。从虚拟机的文件系统可能不会注意到从编辑器中保存的用于实现原子保存的更改。

我正在Mac上使用Sublime Text 3进行编辑,将文件保存到使用NFS安装到Vagrant VM中的文件夹中。正在通过Gulp在本地文件系统上监视文件,并且每当文件更改时,都需要Vagrant主机进行livereload刷新。

使用默认的atomic_save: true使用Sublime Text 3更改单个字符会触发更改,但不会提供更新的文件。在Vim中编辑,TextEdit,Sublime Text 2和TextWrangler均触发更新并提供更新的文件内容。切换到atomic_saves: false可使Sublime Text 3与其他编辑器内联,从而触发更新并提供正确的文件。

Sublime Text 3的默认首选项包括以下注释:

1
2
3
// Save via writing to an alternate file, and then renaming it over the
// original file.
"atomic_save": true,

问题可能与将更改写入未监视的临时文件有关,然后该临时文件替换了我们的监视文件。修改是在写入tempfile时发生的,而不是在替换我们正在观看的文件时发生的,因此不会触发任何更新。 NFS缓存或VirtualBox的NFS网关或类似的东西–中间有很多东西。

在发现这只是一个编辑器设置之前,他们花了很多时间摆弄opcache,Apache mods和Laravel黑客。


如果您正在使用VM(例如Vagrant)并且通过NFS从主机共享文件,则另一种可能性是NFS正在缓存修改时间。这会使Laravel认为缓存的编译模板仍然是最新的。这是我今天遇到的问题,我通过添加NFS挂载选项lookupcache=none解决了它(还有一个有关gulp-watch的相关问题,没有注意到样式表和javascript源文件正在更改)。

我在这里写过:监视文件,了解Vagrant的更改,文件修改时间未更新


尝试避免在管理员中缓存时遇到了同样的问题,因为上传的图片没有刷新。我不建议禁用所有PHP应用程序的缓存,您可以通过更改标头来实现。在app/filters.php中添加/编辑此功能:

1
2
3
4
5
6
Route::filter('after', function($response)
{
    // No caching for pages, you can do some checks before
    $response->header("Pragma","no-cache");
    $response->header("Cache-Control","no-store, no-cache, must-revalidate, max-age=0");
});

此外,别忘了此取自:
http://php.net/manual/zh-CN/opcache.configuration.php#ini.opcache.revalidate-freq

"如果禁用了opcache.validate_timestamps,则将忽略此配置指令。"

对我来说就是这种情况。


我还必须调整日期/时间。

我正在使用phpStorm与VirtualBox Laravel Homestead进行sftp同步文件(因为这将使服务器页面在VM上的加载速度更快)。 除了opcache.revalidate_freq=0修复程序外,我还必须确保Homestead VM的日期/时间早于主机OS。 否则,系统不会认为任何更改。

在ubuntu中,执行sudo dpkg-reconfigure tzdata并设置您的时区。 然后,例如,如果您的主机操作系统当前位于上午11:01:00,则将VM设置为稍早的时间sudo date --set 11:00:50

然后sudo nginx restart。 像魅力一样工作!