3

My workflow is pretty simple:

  1. I delete a file
  2. I call clearstatcache()
  3. I save a new file
  4. I call clearstatcache()

Still, at the end, is_file() returns false for a while before deciding to return true when i refresh 10sec later for example.

It looks like a cache problem, doesn't it?

Here's a piece of my code:

// step 1
$path = 'file_to_delete.jpg';
unlink($path);

// is_file($path) returns false here -- normal behavior
// step 2
clearstatcache();

// step 3 -- some stuff going on on an uploaded image, that leads to:
imagejpeg($imagetosave, $path, 80);

// step 4
clearstatcache();

// is_file() returns false, i have to wait a couple of seconds before it starts returning true

Thank you for your help!

EDIT:

Given all the answers i had, the problem doesn't seem to come from clearstatcache().

But should i add, when i overwrite the file (thus its existing status doesn't change), is_file() returns the good result. but when its existing status actually changes, the problem happens. It would be weird if the error didn't come from clearstatcache(), right? (or something related to this cache indeed)

aaaaaa
  • 2,588
  • 3
  • 26
  • 31
  • Does `is_file()` return true in pre-1st step position? Please provide the complete sample we can run and see that issue happens – zerkms Dec 04 '11 at 20:04
  • 3
    I'm not sure why that is... but note that the first call to `clearstatcache` is useless, as `unlink` automatically clears the cache. – nico Dec 04 '11 at 20:05
  • my guess is you just have a programming error somewhere. simplify your script to the bare minimum needed to produce the issue, to help you debug. – goat Dec 04 '11 at 20:07
  • 2
    Sounds like there is a write cache enabled with the disk. – hakre Dec 04 '11 at 20:28
  • @nico I do know that, but i expected adding it event hough it's not need would solve the issue :p – aaaaaa Dec 04 '11 at 20:33
  • @hakre A write cache? Could you tell me more about that? Is it like a buffer before actually writing to the file system? – aaaaaa Dec 04 '11 at 20:34
  • @zerkms I edited the question to answer yours – aaaaaa Dec 04 '11 at 20:38
  • 1
    @Pioul, exactly. A write cache does exactly that. As you sage the file, check the return value of the privous function if it failed or not instead. Don't stress your filesystem too much with clearstatcache. – hakre Dec 04 '11 at 20:40
  • @hakre The weird thing is that i just run the script again while monitoring what was happening on the ftp (using Filezilla). After saving the new file, i can see it on the ftp, but `is_file` still returns false. Since i can see it instantly, there's no write cache, right? And your solution would work indeed, but it's a quick n' dirty fix :( – aaaaaa Dec 04 '11 at 20:54
  • Surely, the OS file system caching must be transparent? It cannot and should not cause this sort of weirdness, or that would cause an outrageous number of programs to have problems. It's not an OS I'd want to use. I'd suggest reporting this as a PHP bug, for lack of any better ideas. – Boann Dec 05 '11 at 10:07
  • Check is your hard-disk mount as NFS. If so, you know what I mean – ajreal Dec 05 '11 at 17:08

1 Answers1

2

I agree with @hakre, check the result of the create/delete.

It's not quick-and-dirty, even Rasmus himself recommends it:

[2011-03-31 08:34 UTC] rasmus@php.net

You guys realize that the stat cache is per-request, right? You only need to clear the stat cache before a file_exists() call if you A. did a stat for it, and B. either created or deleted it on that request. In which case you shouldn't need to stat it again since the success status of the create/delete will tell you whether the file is there or not. Perhaps for long-running daemons or something this becomes more of an issue, but for a typical web request the stat cache typically saves you dozens of system calls.

If you really insist on using clearstatcache(), the only thing (other than write caching) coming to my mind is, that you mave have a very huge upload folder, containing thousands of files.

Having many, many files in a single folder will definitely slow down re-stating.

If so, try to reduce the number of files to gain stat performance, e.g. by creating multiple folders, one folder for each initial char of your upload filenames, like upload/a/, upload/b/, etc.

Jürgen Thelen
  • 12,745
  • 7
  • 52
  • 71
  • The thing is i simplified the scenario to make the question simple, but the real one involves different scripts doing different tasks (one the deleting, one the creating -called after). Liek you said, and as the PHP doc states, if scripts are differents, the should be no cache problem. but it appears i had one, so i tried to solve it with `clearstatcache()`, but the issue seems to come from a different location, maybe my dear hoster.. And to answer your last point, i'm in a dev env, working on a couple of files, so the problem doesnt come from here i guess :) Thanks for your answer though! – aaaaaa Dec 05 '11 at 16:48