Заставить file_get_contents прочитать файл локального сервера с диска вместо внутреннего кэша - PullRequest
0 голосов
/ 21 октября 2019

Это для файла, читаемого по пути файловой системы (например, /home/someuser/public_html/somedir/somefile.php) - я не говорю о файле, читаемом по URL.

Я обнаружил, что (в PHP 7.1.32 впо крайней мере) file_get_contents может вернуть кэшированное содержимое, а не содержимое, находящееся сейчас на диске, если файл был изменен внешним процессом (например, загрузкой по FTP).

В имеющемся у меня следе доказательств файл былобновлено 9 минут назад, но, тем не менее, file_get_contents вернул кэшированный контент. Рассматриваемый файл был файлом PHP, который ранее был прочитан самим PHP через require_once (или что-то подобное), хотя (очевидно, из-за возраста) для предыдущего HTTP-запроса (хотя также был бы «прочитан» для текущегоrequest).

EDIT / CLARIFICATION: серверный процесс обновит файл на сервере на основе содержимого другого (PHP) файла, если обнаружит, что другой (PHP) файл был обновлен (т.е. имеетболее поздний filemtime). Было замечено, что файл, обновленный процессом сервера, имеет временную метку через 9 минут, но он явно обновлен на основе более старого содержимого файла PHP (чем оно есть в настоящее время).

Серверная среда - Linux/ Cpanel / Apache. OPcache включен для PHP.

Я провел некоторое исследование, но все, что я мог найти, это комментарий к документации PHP для clearstatcache, который дает подсказку, но не дает ответа:

Обратите внимание, что эта функция влияет только на метаданные файла. Однако все функции файловой системы PHP также выполняют свое собственное кэширование фактического содержимого файла. Вы можете использовать директиву realpath_cache_size = 0 в PHP.ini, чтобы отключить кэширование содержимого, если хотите. Время ожидания кэширования содержимого по умолчанию составляет 120 секунд.

Кэширование содержимого не является хорошей идеей во время разработки и для определенных видов приложений, поскольку ваш код может считывать старые данные из файла, содержимое которого вы только что изменили.

Если тайм-аут кэширования контента по умолчанию составляет 120 секунд, почему я видел его кэшированным в течение 9 минут, и какова фактическая настройка для этого в php.ini? (realpath_cache_size, кажется, имеет значение только для отображения «относительных» путей на «абсолютные».)

Как отключить кэширование содержимого для определенного экземпляра вызова на file_get_contents (или другие функции, которые читают из файлов) ?

Мне приходит в голову, что PHP может внутренне использовать свой кэш stat, чтобы определить, что файл явно не был изменен (даже если он имеет) перед возвратом кешированного контента для него, хотя это кажется мне слишком большим кешированием для надежной работы. Тем не менее, сценарий не так просто воспроизвести, и это может быть потрачено впустую усилия, чтобы проверить эту гипотезу, если кто-то уже знает, будет или не будет правдой.

У некоторых из вас есть ещеглубокое знание, и может быть в состоянии пролить свет?

TIA ?

1 Ответ

0 голосов
/ 21 октября 2019

Похоже, что проблема может быть вызвана сохранением временных меток во время загрузки по FTP. Время модификации файла на сервере заканчивается (возможно, значительно) более старой отметкой времени, чем когда файл был фактически изменен на сервере (т.е. когда он был загружен).

Если процесс сервера использует отметку времени дляПосмотрите, нужно ли ему обновить какой-то другой файл, он может определить, что файл не был обновлен, хотя на самом деле он не обновлен, и, таким образом, не обновить другой файл. Это может привести к очевидному поведению, которое вы увидели.

...