3

Web サーバーからの PHP スクリプトの自動データ収集に苦労しています。問題のファイルには気象データが含まれており、10 分ごとに更新されます。奇妙なことに、Web サーバー上の「ファイルの変更」日付は変更されません。

単純なfopen ('http://...') コマンドは、このディレクトリ内の最後のファイルの最新バージョンを 1 時間ごとに取得しようとします。しかし、定期的に、最大 4 時間前のバージョンになってしまいます。これは、(システム管理者が私に保証したように)いかなる種類のプロキシサーバーも使用しない Linux サーバーで発生します。

PHP は独自のキャッシュ機構を実装していますか? または、他に何が干渉している可能性がありますか?

(私の現在の回避策は、動作する exec('wget --nocache...') を介してファイルを取得することです。)

4

5 に答える 5

2

HTTP 経由でファイルを取得しているので、PHP はサーバーが応答するキャッシュ ヘッダーを尊重すると想定しています。

これを回避するための非常に単純で汚い方法は、各リクエストにランダムな get パラメータを追加することです。

于 2009-02-04T14:06:07.873 に答える
2

fopen('http://...') によってアクセスされるコンテンツの観察されたキャッシングに関する Q と投稿者は、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 ソケット対話を行っているため、クライアントのどこでキャッシュが発生するかを想像するのは困難です。サーバー側または中間のプロキシ キャッシングの可能性が残されています。(デフォルトで、txt ファイルの 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
于 2012-02-15T00:46:07.467 に答える