7

I have the following test code in test.php:

<?php
$step = $_GET['step'];
switch($step) {
  case 1:
    include 'foo.php';   # line 5
    file_put_contents('foo.php', '<?php print "bar\\n"; ?>');
    header('Location: test.php?step=2');
  break;
  case 2:
    print "step 2:\n";
    include 'foo.php';
  break;
}
?>

foo.php initially has the following content:

<?php print "foo\n"; ?>

When I call test.php?step=1 in my browser I would expect the following output:

step 2:
bar

But I get this output:

step 2:
foo

When I comment out the include in line 5, I get the desired result. The conclusion is, that PHP caches the content of foo.php. When I reload the page with step=2 I also get the desired result.

Now... why is this and how to avoid this?

9
  • 1
    What version of PHP are you using? Commented Jan 5, 2015 at 19:58
  • 2
    I'd guess that you never get redirected to ?step=2 since you are print'ing data before sending the Location header (which should cause an error). Commented Jan 5, 2015 at 19:58
  • It would not work with commented out line 5 if foo.php would not be overwritten. I also looked into foo.php... It is modified. Commented Jan 5, 2015 at 19:58
  • cOle2: It would not print "step 2:" if it would not get redirected! Commented Jan 5, 2015 at 19:59
  • 1
    If you still believe it is caching, you should check if OpCache is enabled. opcache.enable=0 in your php.ini. Commented Jan 5, 2015 at 20:03

2 Answers 2

9

Assuming you use OPcache, opcache.enable = 0 works.

A more efficient method is to use

opcache_invalidate ( string $script [, boolean $force = FALSE ] )

This will remove the cached version of the script from memory and force PHP to recompile.

Sign up to request clarification or add additional context in comments.

Comments

5

Note that opcache_invalidate is not always available. So it is better to check if it exists. Also, you should check both of opcache_invalidate and apc_compile_file.

Following function will do everything:

    public static function clearCache($path){
        if (function_exists('opcache_invalidate') && strlen(ini_get("opcache.restrict_api")) < 1) {
            opcache_invalidate($path, true);
        } elseif (function_exists('apc_compile_file')) {
            apc_compile_file($path);
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.