Skip to content

Instantly share code, notes, and snippets.

@AndreiTelteu
Last active January 25, 2022 15:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndreiTelteu/a9efddbc0efdbbf32fc3bf9f0b2f985c to your computer and use it in GitHub Desktop.
Save AndreiTelteu/a9efddbc0efdbbf32fc3bf9f0b2f985c to your computer and use it in GitHub Desktop.
How to invalidate an entire directory with opcache, also in a laravel middleware
<?php
$directories = [
    'absolute/path/to/dir',
    'multiple/dirs/if/needed',
];
$extensions = [
    'php',
];
function invalidateDirectory($dir) {
    $dir_iterator = new \RecursiveDirectoryIterator($dir);
    $iterator = new \RecursiveIteratorIterator($dir_iterator, \RecursiveIteratorIterator::SELF_FIRST);

    foreach ($iterator as $file) {
        if (!$file->isFile()) continue;
        if (!in_array($file->getExtension(), $extensions)) continue;

        opcache_invalidate($file->getPathname(), true);
    }
}
foreach ($directories as $dir) {
    invalidateDirectory($dir);
}

If nothing works, fuck opcache and reset all !

<?php opcache_reset();

Laravel

You can apply this in laravel as a middleware to a group of routes, or to all routes. File: /app/Http/Middleware/OpcacheInvalidate.php

<?php

namespace App\Http\Middleware;

use Closure;
use RecursiveIteratorIterator;
use RecursiveDirectoryIterator;
use Illuminate\Http\Request;

class OpcacheInvalidate
{
    
    public function getDirectories() {
        return [
            app_path(),
            resource_path('views'),
            storage_path('framework/views'),
        ];
    }
    
    public function getExtensions() {
        return [
            'php',
        ];
    }
    
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {
        
        foreach ($this->getDirectories() as $dir) {
            $this->invalidateDirectory($dir);
        }
        
        // opcache_reset(); // if nothing works uncomment this
        
        return $next($request);
    }
    
    public function invalidateDirectory($dir)
    {
        $dir_iterator = new RecursiveDirectoryIterator($dir);
        $iterator = new RecursiveIteratorIterator($dir_iterator, RecursiveIteratorIterator::SELF_FIRST);
        $extensions = $this->getExtensions();
        
        foreach ($iterator as $file) {
            if (!$file->isFile()) continue;
            if (!in_array($file->getExtension(), $extensions)) continue;
            
            opcache_invalidate($file->getPathname(), true);
        }
    }
}

Then in /app/Http/Kernel.php to apply this to all routes put this inside $middleware

\App\Http\Middleware\OpcacheInvalidate::class,

Or you can put in the web or api group.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment