The problem with invalidating

According to the official docs, there are 3 functions you can use for interacting with the cache:

  • opcache_compile_file: Compiles and caches a PHP script without executing it
  • opcache_invalidate: Invalidates a cached script
  • opcache_reset: Resets the contents of the opcode cache

You have to use opcache_reset(), to invalidate the cache, but unfortunately the docs don't make it clear, that the cache is tied to the process that is executing PHP, which is either php-fpm, or, if you are using mod_php (and you shouldn't), apache. What this means is that you cannot clear the cache from the CLI, because running a script from the CLI will launch a new process.

There are two solutions that I know of, and I'm not satisfied with either of them:

  1. Restart the FPM/Apache
  2. Create a dummy .php file and access that with curl

Restarting the FPM will involve tinkering with sudoers a bit, since you need to give your regular users the ability to restart it. A graceful restart (sending SIGHUP to it) is enough for the cache to clear. According to a guy in the #php channel on freenode, this is the recommended way to do it.

The dummy file thing is honestly more of a workaround than a solution, but you can create a .php file, and put a single line opcache_reset() into that, upload the file under the webroot, and access it with curl. Because you are accessing it with curl, it will go through the usual webserver -> fpm cycle (instead of spawning a separate process), and it will be executed by the process that we need.

In case you want to do some tests on your own, there are 2 other functions that are not documented anywhere currently for some reason, they are opcache_get_configuration(), and opcache_get_status(), you can use the latter to see what is in the cache. I found these in a stackoverflow answer.