php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #58634 APC stat=off checks for deleted file
Submitted: 2009-04-17 00:50 UTC Modified: 2009-04-17 02:59 UTC
From: stevenrusch at gmail dot com Assigned:
Status: Wont fix Package: APC (PECL)
PHP Version: 5.2.9 OS: Apache/1.3.41 CentOS
Private report: No CVE-ID: None
 [2009-04-17 00:50 UTC] stevenrusch at gmail dot com
Description:
------------
APC stat=off checks require_once requests from cache first without checking if the physical file changed, however, this is not true if the physical file is deleted.

What I did: Set stat=off. Perform apc_compile_file on a php file, then deleted the physical file, then issued require_once to execute the file out of cache. 

Expected results: The php file in the apc cache should have been executed properly using require_once. 

Actual results: When the require_once was issued, a fatal error occurred saying file does not exist, even though it does exist in the apc cache. 

The documentation describes stat=off not checking for changed files, but makes no mention if the file no longer exists. In the spirit of stat=off providing the maximum performance without checking the physical file, this should also include not checking for deleted files as well. If a file in cache needs to be invalidated the appropriate action would be to clear the system cache (for ver 3.0.19) or use the apc_delete_file api(?)(for ver 3.1.1).


Reproduce code:
---------------
index.php file contains:
<?
apc_clear_cache();

echo '<b>require_once after file overwritten</b><br>';
$filename1='/home/apc/public_html/compile1.php';
file_put_contents($filename1,'compile1.php is cached in apc');
apc_compile_file($filename1);
file_put_contents($filename1,'compile1.php file is overwritten');
require_once($filename1);

echo '<br><br><b>require_once after file deleted</b><br>';
$filename2='/home/apc/public_html/compile2.php';
file_put_contents($filename2,'compile2.php is cached in apc');
apc_compile_file($filename2);
unlink($filename2);

print_r(apc_cache_info()); // dump cache before fatal error
require_once($filename2);
?>

You can execute the above code at URL:
http://66.7.210.76/~apc/


Expected result:
----------------
Expected HTTP output:

require_once after file overwritten
compile1.php is cached in apc

require_once after file deleted
(dump of apc cache showing compile1.php and compile2.php reside in the cache)
compile2.php is cached in apc


Actual result:
--------------
Actual HTTP output:

require_once after file overwritten
compile1.php is cached in apc

require_once after file deleted
(dump of apc cache showing compile1.php and compile2.php reside in the cache)
Warning: require_once(/home/apc/public_html/compile2.php) [function.require-once]: failed to open stream: No such file or directory in /home/apc/public_html/index.php on line 18

Fatal error: require_once() [function.require]: Failed opening required '/home/apc/public_html/compile2.php' (include_path='.:/usr/lib/php:/usr/local/lib/php') in /home/apc/public_html/index.php on line 18


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-04-17 01:01 UTC] stevenrusch at gmail dot com
I selected APC ver 3.1.2 when entering this bug but I don't see anyplace it is reporting that. I tried this using APC ver 3.0.19 (stable) and ver 3.1.2 (beta) with same results.
 [2009-04-17 01:35 UTC] rasmus@php.net
Not really something we can fix easily in APC since the check is done at the PHP level. If you want to do something like this, use require instead of require_once and it will work fine.
 [2009-04-17 02:43 UTC] stevenrusch at gmail dot com
I tried "require" vs "require_once" and all works fine just like you said, which works for me. I was under the impression that APC only cached files with include_once & require_once so that is why I never tried their counterparts. 

This information could be something which could help someone down the road if added to the documentation to explain how require and require_once have different effects with apc. Just a thought.

I also want to say just a general thanks for you and anyone else who devotes their time to coding and maintaining these extensions. Your hard work is very much appreciated! Thanks again!

Steve
 [2009-04-17 02:59 UTC] rasmus@php.net
The _once in those statements refer to them doing a once check on the file inclusion.  It has nothing to do with caching.  It just means that a file won't be included twice if you call include_once on it twice.  With include/require it will.  include_once/require_once do extra checks and an open() syscall, so they are quite a bit slower than include/require, especially under an opcode cache like APC.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 06:01:30 2024 UTC