I’d like to know if fstat() is cached.
Documentation says nothing about it.
(PHP 8.1.12)
EDIT:
I made a LOT of tests, I have now an accurate answer for that.
Introduction:
I created two scripts and ran them both simultaneously (locking the file pointer with an exclusive lock (flock($fp, LOCK_EX))* to prevent them from overwriting each other) and on their own; I printed print_r(fstat($fp)) at various stages of a loop that led to writing 5 MB of data. I also used var_dump(realpath_cache_get())
Returns an array of realpath cache entries. The keys are original path entries, and the values are arrays of data items, containing the resolved path, expiration date, and other options kept in the cache.
to detect the realpath cache and ran tests trying to clear and not clear the cache via clearstatcache().
What happened:
I found that the only item that gets cached is ‘atime’
time of last access (Unix timestamp)
, but most upsetting of all: it is not put in the realpath cache, consequently nothing will change if you clear it via clearstatcache(), you can only restart the machine or wait for the cache timeout to clear the data (depending on the machine).
Fortunately this doesn’t affect me since I only need ‘size’ element of fstat. Sadly I cannot give you the source code cause I changed it a lot of time to try all possibilities.
Thank you to everyone who spent time to help me.
*NOTE: Use flock in both files, if you use it only in one the other file will be able to write in the not locked file that has been ran before
CONCLUSION
The only cached element of fstat is atime, but it is not cached in the realpath, so clearstatcache() is useless
2
Answers
I made a quick demo that appears to show that it is not cached. However, see the edit, too
Output:
Edit
Per @Barmar, I ran the test again, this time with just an
fstat
call followed by a sleep(10), then I quickly updated the file with vim manually, and then one finalfstat
call (all in the same request), and that one came back as cached.I then ran that again, this time with
clearstatcache()
before the finalfstat
, and it did not change. I also tried the tests with bothw
andr
modes forfopen
, same results.So there does appear to be a cache of some sort, but I don’t think it is the stat cache.
As a supplement:
I also did exactly such a test as Chris Haas describes in the comment.
Same results for PHP on Win10 and a small Linux.