6

Im having a problem where we run an upgrade for our web application.

After the upgrade script completes and access the web app via the browser, we get file not found errors on require_once() because we shifted some files around and PHP still has the old directory structure cached.

If we have the default 120 seconds for the realpath_cache_ttl to expire, then everything resolves itself, but this is not acceptable for obvious reasons.

So I tried using clearstatcache with limited success. I created a separate file (clearstatcache.php) that only calls this function (this is a one line file), and placed a call to it in our install script via curl:

<?php
clearstatcache(true);

This does not seem to work, however if I call this file via the browser it immediately begins to work.

I'm running PHP version 5.3

I started looking at the request header differences between my browser and curl, and the only thing I can see that might matter is the PHPSESSID cookie.

So my question is, does the current PHPSESSID matter (I don't think it should). Am I doing something wrong with my curl script? I am using

curl -L http://localhost/clearstatcache.php

EDIT: Upon further research, I've decided this probably has something to do with multiple apache processes running. clearstatcache will only clear the cache of the current apache process - when the browser is making a request a different apache process serves the request, and this process still has the old cache.

Martin Konecny
  • 57,827
  • 19
  • 139
  • 159
  • AFAIK `realpath_cache_ttl` and `realpath_cache_size` should only affect the real paths, the paths to the file that exists. At least this is proven by the fact that I have the default values of 120s and 16K on all my projects and I have never experienced such issues. Do you use any opcode cache? – zerkms Feb 12 '12 at 19:45
  • you're correct, the cache is per process. – goat Feb 12 '12 at 20:41

1 Answers1

2

Given that the cache is part of the Apache child process thanks to mod_php, your solution here is probably going to be restarting the Apache server.

If you were using FastCGI (under Apache or another web server), the solution would probably be restarting whatever process manager you were using.

This step should probably become part of your standard rollout plan. Keep in mind that there may be other caches that you might also need to clear.

Charles
  • 50,943
  • 13
  • 104
  • 142
  • As far as I can tell, this is the only solution at the moment. If you could somehow connect to every apache process and clearstatcache then that would be the best solution, but until I figure out how to do that, this is the only solution. – Martin Konecny Feb 17 '12 at 18:14
  • As far as I know, there's no way to direct a HTTP request to a specific Apache child. That *would* be very handy. You might try opening as many persistent connections as there are Apache children, though that's probably going to consume more resources and time than a safe restart. – Charles Feb 17 '12 at 20:08