Ошибка при записи файла в простом PHP-кэшировании - PullRequest
1 голос
/ 20 декабря 2011

Я сделал простой управляемый базой данных сайт php.Сейчас я пытаюсь реализовать простое кэширование на сайте.я пробовал это откуда-то

<?php
      $reqfilename="test";
      $cachetime = 60*5; // 5 minutes
      $cachefile = "cache/".$reqfilename.".html";
      $cf2="cache/".$reqfilename."2.html";
      if (file_exists($cachefile) && ((time() - $cachetime) < filemtime($cachefile))) 
      { 
         include($cachefile);
         exit;
      }
      ob_start(); 
?>
CONTENT OF THE PAGE GOES HERE
<?php   
        $fp = @fopen($cf2, 'w'); 
        if($fp){
            fwrite($fp, ob_get_contents());
            fclose($fp); 
            rename($cf2,$cachefile);
        }   
        ob_end_flush(); 
?>

Но что, если файл кэша переименовывается и кто-то запрашивает страницу.Будет ли отображаться ошибка, или просто у пользователя будет задержка?

Чтобы сократить время изменения только файла кэша, я использую переименование вместо прямой записи в исходный файл кэша

Правильный код для этого (на основе ответа ниже)

<?php
      $reqfilename="test";
      $cachetime = 60*5; // 5 minutes
      $cachefile = "cache/".$reqfilename.".html";

      if (file_exists($cachefile) && ((time() - $cachetime) < filemtime($cachefile))) 
      { 
         include($cachefile);
         exit;
      }
      ob_start(); 
?>
CONTENT OF THE PAGE GOES HERE
<?php   
        $fp = @fopen($cachefile, 'w'); 
    if (flock($fp, LOCK_EX | LOCK_NB)) {
    fwrite($fp, ob_get_contents());
    flock($fp, LOCK_UN);
    fclose($fp); 
    }

    ob_end_flush(); ?>

Ответы [ 2 ]

1 голос
/ 20 декабря 2011

Переименование файла не является источником вашей проблемы. Основное условие гонки с вашим сценарием - множественные запросы, определяющие истекший mtime и все записи в test2.html.

Лучший подход заключается в том, чтобы выполнить исключительную неблокирующую flock (при условии не-windows) сразу после обнаружения истекшего mtime, буферизировать вывод, перезаписать файл и снять блокировку. Если flock возвращает false, тогда другой процесс записывает в него, и текущий процесс должен полностью пропустить запись.

Если во время блокировки сделан запрос, веб-сервер будет ожидать завершения записи файла (и снятия блокировки), а затем обработать файл.

0 голосов
/ 20 декабря 2011

Не думаю, что ваш источник будет работать правильно, потому что вы не удаляете кеш-файл

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...