Laravel开发中的视图缓存问题--无法立即看到更改

23

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

当我们更新视图中的不同信息时,几乎需要5到10分钟才能看到更新后的信息。就像Laravel缓存了视图并设置了TTL一样。

我知道这不是我本地web服务器的问题,因为我使用过其他框架,从未遇到过这个问题。

在搜索互联网时,我找不到一个很好的答案来禁用这个功能。如果每次想要进行更改时视图都需要花费很长时间才能更新,那我想使用Laravel也没有什么用处。实际上,这听起来是相反效果。

有没有办法禁用这个功能?为什么我的视图在开箱即用的情况下需要花费如此长的时间才能更新?


在开发模式下如何禁用模板缓存?可能是重复问题,可参考https://dev59.com/hGQn5IYBdhLWcg3wRVRs。 - Hackerman
@RobertRozas 已经阅读了那个答案,但是说真的吗??除了一些黑客技巧之外,难道没有别的方法吗??这听起来不太对。 - Sethen
我读过的所有帖子都只提到了黑客技巧,甚至在Laravel论坛上也是如此http://forums.laravel.io/viewtopic.php?pid=15066 ....也许那些Laravel的家伙认为这是一种特性xD - Hackerman
1
这个问题涉及到的是 Blade 模板的缓存还是渲染视图上的实际内容? Laravel 默认不会缓存渲染的内容,只会缓存编译后的 Blade 模板(转换成 PHP 代码)。一旦编辑,它应该会自动重新编译。 - Gary Green
请查看此请求 https://github.com/laravel/framework/issues/2501 - Vikas Khunteta
7个回答

29

#laravel IRC频道是个及时雨。这一点与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服务器以使更改生效。


4
可能对一些人来说很明显,但请确保重新启动您的网络服务器(例如Apache或您正在使用的其他服务器),否则更改将不会生效。 - Matt
3
为什么在PHP 5.4上会发生这种情况呢?我没有看到opcache的设置。 - Kyle Ridolfo
@KyleRidolfo 我不确定。你可以尝试在 #laravel IRC 中询问。我不确定5.4是否有OPcache设置。 - Sethen

3

随着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)) {
                @unlink($file);
            }
        }
    }
});

这在Laravel 5.2中对我非常有效。我只是将其设置为中间件。 - Alhassan Abdulkadir
1
@AlhassanAbdulkadir-- 在 Laravel 5.2 中没有 app/filters.php 文件。你把它放在哪里了? - user101289

2

有可能这不是缓存问题,也和 Laravel、Apache 或 PHP 没有任何关系。如果你正在向像 Vagrant 这样的虚拟机共享文件,请确保你的编辑器在写入文件时没有使用 "原子保存"。

为了测试这个问题,可以使用几个不同的文本编辑器对一个被监视的文件进行小修改(单个字符)。从实现了原子保存的编辑器中保存的更改可能不会被 VM 的文件系统注意到。

我正在 Mac 上使用 Sublime Text 3 进行编辑,将文件保存到一个被挂载到 Vagrant VM 的 NFS 中的文件夹中。通过 Gulp 在本地文件系统上监视文件,并在文件更改时从 Vagrant 主机请求 livereload 刷新。

使用默认设置 atomic_save: true 在 Sublime Text 3 中更改单个字符会触发更改,但不会提供更新后的文件。在 Vim、TextEdit、Sublime Text 2 和 TextWrangler 中进行编辑都会触发更新并提供已更新的文件内容。切换到 atomic_saves: 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。

1

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

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");
});

1
如果您使用虚拟机(如Vagrant),并通过NFS从主机共享文件,则另一个可能性是NFS正在缓存修改时间。这会导致Laravel认为已缓存的编译模板仍然是新鲜的。这就是我今天遇到的问题,我通过添加NFS挂载选项lookupcache = none解决了这个问题(以及gulp-watch无法注意到样式表和JavaScript源文件正在改变的相关问题)。
我在这里写了一篇文章:在Vagrant上监视文件更改,文件修改时间不更新

0

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

我使用phpStorm通过sftp同步我的文件({{link1:因为它可以使虚拟机上的服务器页面加载更快}})与VirtualBox Laravel Homestead。除了opcache.revalidate_freq=0修复之外,我还必须确保Homestead VM的日期/时间比主机操作系统旧。否则,系统认为没有任何更改。

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

然后sudo nginx restart。完美解决!


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接