I have a problem with PHP filemtime function. In my webapp I use Smarty template engine with caching option. In my webapp I can do some actions which generate error, but lets focus on only one action. When I click link on page some content is updated - I can click few times and everything is OK but about one request on 10 fails. Following error occurs:
filemtime() [<a href='function.filemtime'>function.filemtime</a>]: stat failed for
and the line that causes the problem:
return ($_template->getCachedFilepath() && file_exists($_template->getCachedFilepath())) ? filemtime($_template->getCachedFilepath()) : false ;
As you can see, file exists because it is checked.
Problematic line of code is included in smarty_internal_cacheresource_file.php
(part of Smarty lib v3.0.6)
App is run on UNIX system, external hosting.
Any ideas? Should I post more details?
file_exists
internally uses the access
system call which checks permissions as the real user, whereas filemtime
uses stat
, which performs the check as the effective user. Therefore, the problem may be rooted in the assumption of effective user == real user, which does not hold. Another explanation would be that the file gets deleted between the two calls.
Since both the result of $_template->getCachedFilepath()
and the existance of the file can change in between system calls, why do you call file_exists
at all? Instead, I'd suggest just
return @filemtime($_template->getCachedFilepath());
If $_template->getCachedFilepath()
can be set to a dummy value such as false
, use the following:
$path = $_template->getCachedFilepath();
if (!$path) return false;
return @filemtime($path);
Use:
Smarty::muteExpectedErrors();
Read this and this
I used filemtime successfully without checking "file_exists" for years. The way I have always interpreted the documentation is that FALSE should be returned from "filemtime" upon any error. Then a few days ago something very weird occurred. If the file did not exist, my Cron job terminated with a result. The result was not in the program output but rather in the Cron output. The message was "file length exceeded". I knew the Cron job ended on the filemtime statement because I sent myself an email before and after that statement. The "after" email never arrived.
I inserted a file_exists check on the file to fix the Cron job. However, that should not have been necessary. I still do not know what was changed on the hosting server I use. Several other Cron jobs started failing on the same day. I do not know yet whether they have anything to do with filemtime.