私は非常に簡単な質問があります:PHPでファイルをダウンロードする最良の方法は何ですか?ただし、ローカルバージョンが5分以上前にダウンロードされた場合のみですか?
私の実際のケースでは、リモートでホストされているcsvファイルからデータを取得したいと思います。
$file = file_get_contents($url);
ローカルコピーやキャッシュなし。これをキャッシュされたバージョンに変換する最も簡単な方法は何ですか?最終結果は変わりません($ fileは同じままです)が、それほど前にフェッチされていない場合(たとえば5分)、ローカルコピーを使用しますか?
ローカルキャッシュファイルを使用し、使用する前にファイルの存在と変更時刻を確認してください。たとえば、_$cache_file
_がローカルキャッシュファイル名の場合:
_if (file_exists($cache_file) && (filemtime($cache_file) > (time() - 60 * 5 ))) {
// Cache file is less than five minutes old.
// Don't bother refreshing, just use the file as-is.
$file = file_get_contents($cache_file);
} else {
// Our cache is out-of-date, so load the data from our remote server,
// and also save it over our cache for next time.
$file = file_get_contents($url);
file_put_contents($cache_file, $file, LOCK_EX);
}
_
(未テストですが、現在使用しているコードに基づいています。)
このコードのどちらの方法でも、$ fileは必要なデータになり、新しい場合はキャッシュを使用するか、そうでない場合はリモートサーバーからデータを取得してキャッシュを更新します。
編集:私は上記を書いて以来、ファイルロックについてもう少し理解しています。ここでファイルのロックを心配しているのであれば、 この答え を読む価値があるかもしれません。
ロックと同時アクセスが心配な場合は、file_put_contentsをtemporaryファイルにしてから rename()
これは、アトミック操作である_$cache_file
_を超えています。つまり、_$cache_file
_は、古いコンテンツまたは完全に新しいコンテンツであり、途中で書き込まれることはありません。
phpFastCache を試してください。ファイルのキャッシュをサポートしており、キャッシュクラスをコーディングする必要はありません。共有ホスティングとVPSで使いやすい
次に例を示します。
<?php
// change files to memcached, wincache, xcache, apc, files, sqlite
$cache = phpFastCache("files");
$content = $cache->get($url);
if($content == null) {
$content = file_get_contents($url);
// 300 = 5 minutes
$cache->set($url, $content, 300);
}
// use ur $content here
echo $content;
これもウィンドウを渡すシンプルなバージョンですUser-Agent
文字列をリモートホストに送信すると、適切なヘッダーがなければ問題の原因になりません。
<?php
function getCacheContent($cachefile, $remotepath, $cachetime = 120){
// Generate the cache version if it doesn't exist or it's too old!
if( ! file_exists($cachefile) OR (filemtime($cachefile) < (time() - $cachetime))) {
$options = array(
'method' => "GET",
'header' => "Accept-language: en\r\n" .
"User-Agent: Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)\r\n"
);
$context = stream_context_create(array('http' => $options));
$contents = file_get_contents($remotepath, false, $context);
file_put_contents($cachefile, $contents, LOCK_EX);
return $contents;
}
return file_get_contents($cachefile);
}
最初に、設計パターンをチェックすることをお勧めします: 遅延読み込み 。
実装は常にローカルキャッシュからファイルをロードするように変更する必要があります。ローカルキャッシュが存在しないか、ファイルの時間ジッターが5分を超える場合は、サーバーからファイルをフェッチします。
疑似コードは次のようなものです。
$time = filetime($local_cache)
if ($time == false || (now() - $time) > 300000)
fetch_localcache($url) #You have to do it yourself
$file = fopen($local_cache)
任意のタイプのデータベースシステムを使用している場合は、このファイルをそこにキャッシュできます。キャッシュされた情報用のテーブルを作成し、少なくとも以下のフィールドを指定します。
これで、上記のスクリプトを次回実行するときに、まずデータベースで識別子を確認し、タイムスタンプを取得します。現在の時刻と保存されているタイムスタンプの差が5分を超える場合は、URLから取得してデータベースを更新します。それ以外の場合は、データベースからファイルをロードします。
データベースを設定していない場合は、ファイルを使用して同じことを行うことができます。1つのファイルまたはファイル内のフィールドには、最後にファイルをダウンロードしたときのタイムスタンプが含まれます。