PHP clearstatcache() question

  • PolishHurricane
  • Mastermind
  • Mastermind
  • User avatar
  • Posts: 1585

Post 3+ Months Ago

I have a file that I modify multiple times in 1 script and I cannot have it cached because I run filemtime() on it. So I need to use clearstatcache after I call it, I'm wondering though...

In the parameters for the function, it mentions you can clear the "realpath cache", anybody know what that is? Or does anybody know how big the actual stat cache is? I read on a PHP bug page that it is only 1 entry big? Now I'm confused... :(

Note: I did set the parameters to TRUE and <FILE_PATH> and it indeed still clears the cache for that file, just not sure if it still clears the caches for all other files.
  • Anonymous
  • Bot
  • No Avatar
  • Posts: ?
  • Loc: Ozzuland
  • Status: Online

Post 3+ Months Ago

  • joebert
  • Fart Bubbles
  • Genius
  • User avatar
  • Posts: 13503
  • Loc: Florida

Post 3+ Months Ago

Here's the source for clearstatcache in PHP php-5.2.14 if it helps.

C Code: [ Select ]
PHPAPI void php_clear_stat_cache(TSRMLS_D)
{
   if (BG(CurrentStatFile)) {
      efree(BG(CurrentStatFile));
      BG(CurrentStatFile) = NULL;
   }
   if (BG(CurrentLStatFile)) {
      efree(BG(CurrentLStatFile));
      BG(CurrentLStatFile) = NULL;
   }
   realpath_cache_clean(TSRMLS_C);
}
 
PHP_FUNCTION(clearstatcache)
{
   if (ZEND_NUM_ARGS()) {
      WRONG_PARAM_COUNT;
   }
   php_clear_stat_cache(TSRMLS_C);
}
  1. PHPAPI void php_clear_stat_cache(TSRMLS_D)
  2. {
  3.    if (BG(CurrentStatFile)) {
  4.       efree(BG(CurrentStatFile));
  5.       BG(CurrentStatFile) = NULL;
  6.    }
  7.    if (BG(CurrentLStatFile)) {
  8.       efree(BG(CurrentLStatFile));
  9.       BG(CurrentLStatFile) = NULL;
  10.    }
  11.    realpath_cache_clean(TSRMLS_C);
  12. }
  13.  
  14. PHP_FUNCTION(clearstatcache)
  15. {
  16.    if (ZEND_NUM_ARGS()) {
  17.       WRONG_PARAM_COUNT;
  18.    }
  19.    php_clear_stat_cache(TSRMLS_C);
  20. }


It appears to keep track of only the last file used. I did the following test. If I run the test as-is, and go in via FTP to delete all three txt files while the script is sleep()-ing, I get errors for the first two files, and a valid mtime for the last file. If I uncomment my clearstatcache() call, I get three errors.

This leads me to believe PHP only keeps a record of the last file, and not a collection of files used throughout the script.

PHP Code: [ Select ]
<pre><?php
 
$filenames = array(
   'one.txt',
   'two.txt',
   'three.txt'
);
 
foreach($filenames as $filename)
{
   file_put_contents($filename, $filename);
}
 
sleep(2);
 
foreach($filenames as $filename)
{
   printf('%1$s: %2$s%3$s', $filename, filemtime($filename), PHP_EOL);
}
flush(); ob_flush();
//clearstatcache();
 
sleep(10); // Delete files via FTP/SSH here
 
foreach($filenames as $filename)
{
   printf('%1$s: %2$s%3$s', $filename, filemtime($filename), PHP_EOL);
}
flush();
 
?></pre>
  1. <pre><?php
  2.  
  3. $filenames = array(
  4.    'one.txt',
  5.    'two.txt',
  6.    'three.txt'
  7. );
  8.  
  9. foreach($filenames as $filename)
  10. {
  11.    file_put_contents($filename, $filename);
  12. }
  13.  
  14. sleep(2);
  15.  
  16. foreach($filenames as $filename)
  17. {
  18.    printf('%1$s: %2$s%3$s', $filename, filemtime($filename), PHP_EOL);
  19. }
  20. flush(); ob_flush();
  21. //clearstatcache();
  22.  
  23. sleep(10); // Delete files via FTP/SSH here
  24.  
  25. foreach($filenames as $filename)
  26. {
  27.    printf('%1$s: %2$s%3$s', $filename, filemtime($filename), PHP_EOL);
  28. }
  29. flush();
  30.  
  31. ?></pre>


In the clearstatcache manual page, the note about the filename argument lists PHP 5.3 so I'm guessing PHP 5.3+ actually maintains the cache for the collection of files used.

I tried to pass the parameters to clearstatcache in PHP 5.2.6 which I have sitting here next to me. I get the following error, which when I look back at the source code for clearstatcache, makes sense because it's throwing a "WRONG_PARAM_COUNT;" error any time there's one or more arguments passed in 5.2.*

Quote:
Wrong parameter count for clearstatcache()


Then we have the source code for clearstatcache in PHP 5.3.3 which accepts arguments. It appears to only use the $filename argument if the realpath argument is TRUE though.

C Code: [ Select ]
PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, int filename_len TSRMLS_DC)
{
   /* always clear CurrentStatFile and CurrentLStatFile even if filename is not NULL
    * as it may contains outdated data (e.g. "nlink" for a directory when deleting a file
    * in this directory, as shown by lstat_stat_variation9.phpt) */
   if (BG(CurrentStatFile)) {
      efree(BG(CurrentStatFile));
      BG(CurrentStatFile) = NULL;
   }
   if (BG(CurrentLStatFile)) {
      efree(BG(CurrentLStatFile));
      BG(CurrentLStatFile) = NULL;
   }
   if (clear_realpath_cache) {
      if (filename != NULL) {
         realpath_cache_del(filename, filename_len TSRMLS_CC);
      } else {
         realpath_cache_clean(TSRMLS_C);
      }
   }
}
 
PHP_FUNCTION(clearstatcache)
{
   zend_bool  clear_realpath_cache = 0;
   char      *filename             = NULL;
   int        filename_len         = 0;
 
   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bs", &clear_realpath_cache, &filename, &filename_len) == FAILURE) {
      return;
   }
 
   php_clear_stat_cache(clear_realpath_cache, filename, filename_len TSRMLS_CC);
}
  1. PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, int filename_len TSRMLS_DC)
  2. {
  3.    /* always clear CurrentStatFile and CurrentLStatFile even if filename is not NULL
  4.     * as it may contains outdated data (e.g. "nlink" for a directory when deleting a file
  5.     * in this directory, as shown by lstat_stat_variation9.phpt) */
  6.    if (BG(CurrentStatFile)) {
  7.       efree(BG(CurrentStatFile));
  8.       BG(CurrentStatFile) = NULL;
  9.    }
  10.    if (BG(CurrentLStatFile)) {
  11.       efree(BG(CurrentLStatFile));
  12.       BG(CurrentLStatFile) = NULL;
  13.    }
  14.    if (clear_realpath_cache) {
  15.       if (filename != NULL) {
  16.          realpath_cache_del(filename, filename_len TSRMLS_CC);
  17.       } else {
  18.          realpath_cache_clean(TSRMLS_C);
  19.       }
  20.    }
  21. }
  22.  
  23. PHP_FUNCTION(clearstatcache)
  24. {
  25.    zend_bool  clear_realpath_cache = 0;
  26.    char      *filename             = NULL;
  27.    int        filename_len         = 0;
  28.  
  29.    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bs", &clear_realpath_cache, &filename, &filename_len) == FAILURE) {
  30.       return;
  31.    }
  32.  
  33.    php_clear_stat_cache(clear_realpath_cache, filename, filename_len TSRMLS_CC);
  34. }


I don't believe I have a copy of 5.3 to run my test on at the moment.

Post Information

  • Total Posts in this topic: 2 posts
  • Users browsing this forum: Liamw411 and 108 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.