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

25,391

Solution 1

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.

Solution 2

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

Solution 3

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.

Solution 4

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

Solution 5

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");
});
Share:
25,391

Related videos on Youtube

Sethen
Author by

Sethen

Software Engineer extraordinaire. Contribute to my projects: https://github.com/sethen

Updated on July 05, 2020

Comments

  • Sethen
    Sethen almost 4 years

    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?

    • Hackerman
      Hackerman over 10 years
    • Sethen
      Sethen over 10 years
      @RobertRozas Already read that answer, but seriously?? Is there no way around this besides a hack?? That doesn't sound right.
    • Hackerman
      Hackerman over 10 years
      All the post i read, just mention hacks, even in the laravel forums forums.laravel.io/viewtopic.php?pid=15066 ....maybe those laravel guys see that like a feature xD
    • Gary Green
      Gary Green over 10 years
      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.
    • Vikas Khunteta
      Vikas Khunteta about 9 years
  • Matt
    Matt about 10 years
    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.
  • Kyle Ridolfo
    Kyle Ridolfo about 10 years
    Any idea why this would happen on PHP 5.4? I don't see settings for opcache.
  • Sethen
    Sethen about 10 years
    @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.
  • Alhassan Abdulkadir
    Alhassan Abdulkadir about 8 years
    This worked great for me in Laravel 5.2. I just set it up as MiddleWare
  • user101289
    user101289 almost 8 years
    @AlhassanAbdulkadir-- there's no app/filters.php in Laravel 5.2. Where did you put this?