22

Some friends and I decided to start working on a project and we came across Laravel and thought it might be a good tool. We started using it locally to develop out some of our pages and noticed something strange.

When we update a view with different information, it would take almost 5 to 10 minutes before the views information would change. It's like Laravel is caching the view and put a TTL on it.

I know this isn't anything I am doing on my local web server because I have used other frameworks and I have never encountered this issue.

Upon searching the Internet, I can't find a great answer on how to disable this. I want to use Laravel, but find it worthless if it takes a while for my views to update each time I want to make a change. In fact, it sounds counter productive.

Is there any way to disable this? Why are my views taking forever to update right out of the box?

Sethen
  • 11,140
  • 6
  • 34
  • 65
  • Possible dup on http://stackoverflow.com/questions/16971445/how-i-can-disable-templates-caching-in-development-mode – Hackerman Dec 14 '13 at 02:59
  • @RobertRozas Already read that answer, but seriously?? Is there no way around this besides a hack?? That doesn't sound right. – Sethen Dec 14 '13 at 03:00
  • All the post i read, just mention hacks, even in the laravel forums http://forums.laravel.io/viewtopic.php?pid=15066 ....maybe those laravel guys see that like a feature xD – Hackerman Dec 14 '13 at 03:06
  • 1
    Is this question related to caching of the blade templates or actual content on the rendered views? Laravel does not cache content rendered by default, only blade compiled (to php) templates. And this should automatically be re-compiled once edited. – Gary Green Dec 14 '13 at 16:14
  • check this request https://github.com/laravel/framework/issues/2501 – Vikas Khunteta May 04 '15 at 07:48

7 Answers7

28

The #laravel IRC channel is a God send. This had nothing to do with Laravel's behavior at all. This was actually something PHP 5.5 was doing.

The reason this was so baffling is because I upgraded my PHP version from 5.3 and never had this issue.

In your .ini file, you need to tweak your OPcache settings. For me, these settings began at line 1087 in the .ini file and looked something like this:

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

Take particular note of the opcache.revalidate_freq=60. This is what is actually making your views cache. If this is not the desired behavior, set the value to 0 and your views will update every time you make a change. Yay!

EDIT AUGUST 21, 2014

As mentioned by Matt below, make sure to restart your web server to see your changes take effect after you have changed your .ini file.

Sethen
  • 11,140
  • 6
  • 34
  • 65
  • 4
    Might be obvious to some, but make sure to restart your webserver (i.e. apache or whatever you are using). Or, else the changes don't take effect. – Matt Mar 08 '14 at 21:56
  • 3
    Any idea why this would happen on PHP 5.4? I don't see settings for opcache. – Kyle Ridolfo Mar 31 '14 at 17:14
  • @KyleRidolfo I am not sure. You may want to try asking in the #laravel IRC. I am not sure if 5.4 has the OPcache settings. – Sethen Apr 01 '14 at 16:48
3

With newer versions of PHP, opcache doesn't work. This is what I use (in 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);
            }
        }
    }
});
Wendtly
  • 61
  • 4
2

It's possible this isn't a caching issue at all and doesn't have anything to do with Laravel, Apache or PHP. If you're sharing files into a Virtual Machine like Vagrant, be sure your editor is not using "Atomic Saves" when writing files.

To test this, make a small edit (single character) to a watched file using several different text-editors. Changes saved from editors which implement atomic saves likely won't be noticed by the VM's filesystem.

I'm editing with Sublime Text 3 on a Mac, saving files to a folder which is mounted into a Vagrant VM with NFS. Files are being watched on the local filesystem via Gulp and a livereload refresh is requested from the Vagrant host whenever a file changes.

Changing a single character with Sublime Text 3 using the default atomic_save: true triggers a change but doesn't serve the updated file. Editing in Vim, TextEdit, Sublime Text 2 and TextWrangler all triggered updates and served the updated file contents. Switching to atomic_saves: false brings Sublime Text 3 inline with the other editors, triggering an update and serving the correct file.

Sublime Text 3's default preferences includes this comment:

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

The problem might have something to do with changes being written to an unwatched tempfile, then that tempfile replacing our watched file. The modification happens when the tempfile is written, not when it replaces the file we're watching, so no update is triggered. That or something with the NFS cache or VirtualBox's NFS gateway -- there's a lot of stuff in the middle.

Many hours were wasted fiddling with opcache, Apache mods and Laravel hacks before discovering this was just an editor setting.

joemaller
  • 19,579
  • 7
  • 67
  • 84
1

I had the same problem trying to avoid cache in the admin since the uploaded images were not refreshing. I don't recommend to disable cache for all your php apps, you can do it changing the headers. Add/Edit this function in 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");
});
Tomas Ramirez Sarduy
  • 17,294
  • 8
  • 69
  • 85
1

Another possibility if you're using a VM (like Vagrant) and it is sharing files from your host via NFS is that NFS is caching the modification times. This would lead Laravel to think that the cached compiled templates are still fresh. This is the problem I had today, and I solved it (and a related problem of gulp-watch not noticing that stylesheet and javascript source files were changing) by adding the NFS mount option lookupcache=none.

I wrote about it here: Watching files for changes on Vagrant, file modification times not updating

Community
  • 1
  • 1
tremby
  • 9,541
  • 4
  • 55
  • 74
0

I had to also adjust the date/time.

I'm using phpStorm to sftp sync my files (since it will keep server pages loading faster on the VM) with VirtualBox Laravel Homestead. In addition to the opcache.revalidate_freq=0 fix, I had to also make sure the Homestead VM had a date/time that was older than the host OS. Otherwise the system doesn't think anything has changed.

In ubuntu, do sudo dpkg-reconfigure tzdata and set your timezone. Then if for example your host OS is currently at 11:01:00 am, set the VM to a slightly older time sudo date --set 11:00:50.

Then sudo nginx restart. Worked like a charm!

prograhammer
  • 20,132
  • 13
  • 91
  • 118
0

Futhermore, don't forget this taken from: http://php.net/manual/en/opcache.configuration.php#ini.opcache.revalidate-freq

"This configuration directive is ignored if opcache.validate_timestamps is disabled."

Which was the case for me.

qwertzman
  • 784
  • 1
  • 9
  • 23