Ошибка при записи файла при простом кэшировании PHP

Я создал простой веб-сайт 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(); ?> 

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

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

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

 <?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(); ?> 

Related of "Ошибка при записи файла при простом кэшировании PHP"

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

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

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

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