2012-02-23 8 views
3

これはうまく動作します。PHPでキャッシュされた画像をキャッシュ

しかし、問題は画像が変更されても同じ名前です。私のキャッシュシステムは、イメージが変更されたことを認識し、古いキャッシュファイルを削除して新しいキャッシュファイルを作成し、それから自分のキャッシュから新しいサイズ変更キャッシュファイルを提供します。しかし、私のシステムやウェブブラウザのキャッシュに問題があります。

イメージが変更されると、スクリプトは200 OKヘッダー(変更されたファイル)を送信します...ただし、イメージプレビューは変更されず、ブラウザで手動でF5キーを押すまで応答は200 OKです。その後、もう一度200 OKを送信してイメージを変更し、それ以降は304を変更しません(必要に応じて)。しかし、問題は、200 OKがブラウザにキャッシュされたファイルを変更しない理由を私はブラウザにキャッシュされた画像を変更するにはF5キーを押す必要があることを...私にはわからないです...

コード:

<?php 

// Image manipulation script 

include("../../../Init.php"); 

if(!isset($_GET["File"])) 
    return; 

$sFullFile = urldecode($_GET["File"]); 

$pData = pathinfo($sFullFile); 

// Options 
$sActions = isset($_GET["Actions"]) ? $_GET["Actions"] : ""; 
$iMaxWidth = isset($_GET["MaxWidth"]) ? (int)$_GET["MaxWidth"] : 0; 
$iMaxHeight = isset($_GET["MaxHeight"]) ? (int)$_GET["MaxHeight"] : 0; 
$bSaveAspect = isset($_GET["SaveAspect"]) & $_GET["SaveAspect"] == "0" ? false : true; 

// Cache control 
$sPathCacheString = md5($pData["dirname"]); 
$sFileCacheString = md5($pData["basename"]); 
$pLastModTime = filemtime($sFullFile); 
$sOptCacheString = md5($sActions . $iMaxWidth . $iMaxHeight . $bSaveAspect); 

$sCacheFile = ImageCache::GetImageManipulatorCacheFileName($sFullFile, $sActions, $iMaxWidth, $iMaxHeight, $bSaveAspect); 

header("Cache-Control: private, max-age=2592000, pre-check=2592000, must-revalidate"); 
header("Pragma: private"); 
header("Expires: " . date(DATE_RFC822, strtotime(" 30 day"))); 

$sLastModString = gmdate("D, d M Y H:i:s \G\M\T", $pLastModTime); 
if(isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) && strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]) >= $pLastModTime) 
{ 
    header("HTTP/1.0 304 Not Modified"); 
    return; 
} 
else 
{ 
    $pImage = new Image($sFullFile); 

    @unlink($sCacheFile); 

    if(GetFlag("ResizeMax", $sActions)) 
    { 
     if($pImage->GetWidth() > $iMaxWidth || $pImage->GetHeight() > $iMaxHeight) 
      $pImage->ResizeImage($iMaxWidth, $iMaxHeight, $bSaveAspect); 
    } 

    Cache::WriteFile($sCacheFile, $pImage->GetOutput());  

    header("Last-Modified: $sLastModString"); 
    header("Content-type: " . $pImage->GetMIMEType()); 
    $pImage->Destroy(); 

    Cache::StreamOut($sCacheFile); 
} 


/* 

    Copyright (C) 2010. Determinanta 
    http://www.determinanta.hr 
    Part of WebSuite aplication platform. All rights reserved. 

*/ 


?> 

EDIT:

を解決しました

私はそれを解決しました...問題は$ _SERVER ["HTTP_IF_MODIFIED_SINCE"]をチェックしていました...キャッシュされたファイルは、変更されていない場合にのみ提供されます。私はこのことを解決するために全日朝にかかった...すべての入力人に感謝します。乾杯。

<?php 

// Image manipulation script 

include("../../../Init.php"); 

if(!isset($_GET["File"])) 
    return; 

$sFullFile = urldecode($_GET["File"]); 

$pData = pathinfo($sFullFile); 

// Options 
$sActions = isset($_GET["Actions"]) ? $_GET["Actions"] : ""; 
$iMaxWidth = isset($_GET["MaxWidth"]) ? (int)$_GET["MaxWidth"] : 0; 
$iMaxHeight = isset($_GET["MaxHeight"]) ? (int)$_GET["MaxHeight"] : 0; 
$bSaveAspect = isset($_GET["SaveAspect"]) & $_GET["SaveAspect"] == "0" ? false : true; 

// Cache control 
$sPathCacheString = md5($pData["dirname"]); 
$sFileCacheString = md5($pData["basename"]); 
$pLastModTime = filemtime($sFullFile); 
$sOptCacheString = md5($sActions . $iMaxWidth . $iMaxHeight . $bSaveAspect); 

$sCacheFile = ImageCache::GetImageManipulatorCacheFileName($sFullFile, $sActions, $iMaxWidth, $iMaxHeight, $bSaveAspect); 
$sFullCacheFile = CACHE_PATH . "/" . $sCacheFile; 

$bCacheNotModified = true; 
if(!is_file($sFullCacheFile)) 
    $bCacheNotModified = false; 
else 
{ 
    if(filemtime($sFullCacheFile) != $pLastModTime) 
     $bCacheNotModified = false; 
} 

$sLastModString = gmdate("D, d M Y H:i:s \G\M\T", $pLastModTime); 
if($bCacheNotModified) 
{ 
    header("HTTP/1.0 304 Not Modified"); 
    return; 
} 
else 
{    
    $pImage = new Image($sFullFile); 

    @unlink($sCacheFile); 

    if(GetFlag("ResizeMax", $sActions)) 
    { 
     if($pImage->GetWidth() > $iMaxWidth || $pImage->GetHeight() > $iMaxHeight) 
      $pImage->ResizeImage($iMaxWidth, $iMaxHeight, $bSaveAspect); 
    } 

    Cache::WriteFile($sCacheFile, $pImage->GetOutput()); 
    touch($sFullCacheFile, $pLastModTime); 

    header("Cache-Control: private, max-age=2592000, pre-check=2592000, must-revalidate"); 
    header("Pragma: private"); 
    header("Expires: " . date(DATE_RFC822, 0)); 
    header("Last-Modified: $sLastModString"); 
    header("ETag: \"" . $sImageMD5 . "\""); 
    header("Content-type: " . $pImage->GetMIMEType()); 

    $pImage->Destroy(); 

    Cache::StreamOut($sCacheFile); 
} 


/* 

    Copyright (C) 2010. Determinanta 
    http://www.determinanta.hr 
    Part of WebSuite aplication platform. All rights reserved. 

*/ 


?> 

答えて

0

あなたが直面している問題はブラウザです。私はレスポンスコードとヘッダーでそれと戦おうとしましたが、最終的にブラウザが新しい画像を取得する唯一の確実な方法は、タイムスタンプなどのURLに一意の文字列を追加することです。

<img src="path/to/your/php/script.php?<?= time(); ?>"/> 
+1

はい、私はこの問題を回避するために知っているが、この方法の問題点は、このSRCパスについてため、ファイルがキャッシュすることはありませんということです新しい画像として(いつも時間()の番号が変わっているので)... – StjepanV

+0

合意しました。そのため、time()関数を追加するかどうかを決定するロジックが必要です。あなたのコードでは、イメージが変更されている場合はPHP側で既に知っているので、同じロジックを使用してタイムスタンプを追加するかどうかを決定します。 – davidethell

0

あなたは、画像のヘッダにてETag(エンティティタグ)を設定しようとしたことがあり:一つの簡単な解決策は、次のように画像の変更はHTMLソースで現在のタイムスタンプを付加する場合ということですか?

MD5変数への画像、そしてそのようにETagを設定します。

header("ETag: \"".$img_md5."\"); 
+0

それは動作しません。 – StjepanV

+0

あなたはこれを回避しようとしているかどうかわからない申し訳ありません。最近私は開発時に何もキャッシュしないようにChromeに指示していました。私は新しいリリースを行うたびにcache.manifestを使用してクライアントサイドキャッシュを強制的に削除します。 –

+0

はい... Chromeはキャッシングが大変です...私はテストと開発にFirefoxを使用しています。私は何をすべきかわからない...ローカルブラウザのキャッシュファイルを削除する方法はありますか? – StjepanV

関連する問題