Реализует ли PHP-функция fopen какой-то кеш? - PullRequest
3 голосов
/ 04 февраля 2009

Я борюсь с автоматическим сбором данных PHP-скрипта с веб-сервера. Указанные файлы содержат метеоданные и обновляются каждые 10 минут. Как ни странно, дата «изменения файла» на веб-сервере не меняется.

Простая команда fopen ('http: // ...') пытается получить самую свежую версию последнего файла в этом каталоге каждый час. Но регулярно я получаю версию до 4 часов. Это происходит на сервере Linux, который (как уверял меня мой системный администратор) не использует прокси-сервер любого типа.

Реализует ли PHP собственный механизм кэширования? Или что еще может мешать здесь?

(Мой текущий способ - захватить файл через exec ('wget --nocache ...'), который работает.)

Ответы [ 5 ]

2 голосов
/ 04 февраля 2009

Поскольку вы получаете файл через HTTP, я предполагаю, что PHP будет обрабатывать любые заголовки кэша, на которые отвечает сервер.

Очень простой и грязный способ избежать этого - добавлять к каждому запросу некоторый случайный параметр get.

1 голос
/ 15 февраля 2012

Вопрос касался наблюдаемого кэширования контента, к которому обращается fopen ('http: // ...'), и автор задавался вопросом, реализует ли PHP собственный механизм кэширования? Другие ответы включали в себя некоторые предположения, но, конечно, самый простой способ выяснить это - проверить, посмотрев на исходный код или, возможно, упростить инструментарий системных вызовов, чтобы увидеть, что происходит? Это легко сделать в системах Debian следующим образом:

$ echo "Hello World" > /var/www/xx.txt
$ strace -tt -o /tmp/strace  \
> php -r 'echo file_get_contents("http://localhost/xx.txt");'
Hello World

Я включил соответствующую выдержку из журналов strace ниже, но это показывает, что PHP RTS просто подключается к localhost: 80 , отправляет «GET /xx.txt», получает ответ содержит заголовки и содержимое файла, которые затем отображаются в STDOUT.

Абсолютно никакое кэширование на стороне клиента не происходит в PHP RTS, и, поскольку он выполняет прямой диалог сокетов HTTP, трудно представить, где на клиенте может происходить кэширование. У нас остается возможность кэширования на стороне сервера или промежуточного прокси. (Обратите внимание, я по умолчанию истекаю Access + 7 дней для текстовых файлов).

Извлечение файла журнала

00:15:41.887904 socket(PF_INET6, SOCK_STREAM, IPPROTO_IP) = 3
00:15:41.888029 fcntl(3, F_GETFL)       = 0x2 (flags O_RDWR)
00:15:41.888148 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
00:15:41.888265 connect(3, {sa_family=AF_INET6, sin6_port=htons(80), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = -1 EINPROGRESS (Operation now in progress)
00:15:41.888487 poll([{fd=3, events=POLLIN|POLLOUT|POLLERR|POLLHUP}], 1, 60000) = 1 ([{fd=3, revents=POLLOUT}])
00:15:41.888651 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
00:15:41.888838 fcntl(3, F_SETFL, O_RDWR) = 0
00:15:41.888975 sendto(3, "GET /xx.txt HTTP/1.0\r\n", 22, MSG_DONTWAIT, NULL, 0) = 22
00:15:41.889172 sendto(3, "Host: localhost\r\n", 17, MSG_DONTWAIT, NULL, 0) = 17
00:15:41.889307 sendto(3, "\r\n", 2, MSG_DONTWAIT, NULL, 0) = 2
00:15:41.889437 poll([{fd=3, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout)
00:15:41.889544 poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}], 1, 60000) = 1 ([{fd=3, revents=POLLIN}])
00:15:41.891066 recvfrom(3, "HTTP/1.1 200 OK\r\nDate: Wed, 15 F"..., 8192, MSG_DONTWAIT, NULL, NULL) = 285
00:15:41.891235 poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}], 1, 60000) = 1 ([{fd=3, revents=POLLIN}])
00:15:41.908909 recvfrom(3, "", 8192, MSG_DONTWAIT, NULL, NULL) = 0
00:15:41.909016 poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}], 1, 60000) = 1 ([{fd=3, revents=POLLIN}])
00:15:41.909108 recvfrom(3, "", 8192, MSG_DONTWAIT, NULL, NULL) = 0
00:15:41.909198 close(3)                = 0
00:15:41.909323 write(1, "Hello World\n", 12) = 12
00:15:41.909532 munmap(0x7ff3866c9000, 528384) = 0
00:15:41.909600 close(2)                = 0
00:15:41.909648 close(1)                = 0
1 голос
/ 04 февраля 2009

Так что, если я вас правильно понимаю, часть проблемы может заключаться в том, что файл * .dat всегда имеет отметку времени 1:00 AM? Есть ли у вас контроль над сервером, содержащим данные (http://www.iac.ethz.ch/php/chn_meteo_roof/)? Если это так, вы должны попытаться выяснить, почему данные всегда имеют одну и ту же метку времени. Я должен верить, что он установлен преднамеренно - операционная система будет обновлять метку времени при изменении файла, если только вы не сделаете все возможное, чтобы это не произошло. Если вы не можете понять, почему он установлен в 1:00, вы можете, по крайней мере, выполнить команду «touch» для файла, которая обновит его модифицированную временную метку.

Это все, конечно, если у вас есть доступ к серверу, предоставляющему файлы.

0 голосов
/ 04 февраля 2009

возможно, это может решить вашу проблему (запрос POST не может быть кэширован, насколько я знаю)

$opts = array('http' =>
  array(
    'method'  => 'POST',
    'content'=>''
  )
);
$context  = stream_context_create($opts);
$resource = fopen ('http://example.com/your-ulr', 'r', false, $context);

/* or you can use file_get_contents to retrieve all the file 
   $fileContent = file_get_contents('http://example.com/your-ulr', false, $context);
*/
0 голосов
/ 04 февраля 2009

почему бы не попробовать curl , я думаю, что это более правильное использование для этого.

...