7

I have this code in my application, often run in race condition by severals users of my application

clearstatcache(TRUE, $filepath);
if(file_exists($filepath)) unlink($filepath);

But, for this line of code, I still have severals errors each day like

unlink(file): No such file or directory

Server run Apache 2.2 and PHP 5.3.3. I know race problem, but think @ operator is just evil. I have first tried without any parameter for clearstatcache(), with the same error. How can I do it the correct way?

Cédric Girard
  • 3,358
  • 7
  • 37
  • 52
  • could you add a bit of your code please. – S L Apr 05 '11 at 08:15
  • @experimentX but it's right there, isn't it? – Pekka Apr 05 '11 at 08:17
  • @Pekka well, i don't see any flaw in the code above, i guess – S L Apr 05 '11 at 08:19
  • In this case the @ operator might not be too evil *awaits death by comments*. Depends on how critical this bit of code is. – JohnP Apr 05 '11 at 08:19
  • Like @John says, there may not be anything you *can* do except suppress the warning. – Pekka Apr 05 '11 at 08:22
  • How does clearstatcache() work? It's strange the file exists when testing with file_exists() and then it does exist anymore... Several processes trying to delete the same file at the same time maybe? – Capsule Apr 05 '11 at 08:30
  • Yes, severals processes run this code. It's a big race condition. My problem is that I need to check if I have actually deleted the file, so @ and a check with file_exists() after the unlink may just be fine. – Cédric Girard Apr 05 '11 at 09:35
  • Maybe there is some OS related "caching"? Try to add a `usleep(100)` after `clearstatcache()` – powtac Apr 05 '11 at 09:48

2 Answers2

6

you can try this

if(@unlink($path)) {
  echo "Deleted file "; 
}
else{
  echo "File can't be deleted";
}

I think it will be pretty fine;

Headshota
  • 21,021
  • 11
  • 61
  • 82
  • 1
    He says in his question that he doesn't want to use this. It may be the only option, though. – Pekka Apr 05 '11 at 08:22
5

As said in comment, my need is to be sure I have deleted the file, not to know witch process delete it, so

@unlink($filepath);
clearstatcache(TRUE, $filepath);
if(file_exists($filepath)) throw new Exception('file not deleted : ' . $filepath);

may be a better way.

Thanks a lot for your help, it's so much easier to think another way to do it with severals comments.

Cédric Girard
  • 3,358
  • 7
  • 37
  • 52