2009-09-06 13 views
20

Tôi hoàn toàn mới về cách lưu hình ảnh.Làm cách nào để trình duyệt lưu hình ảnh, với php?

Tôi xuất tất cả hình ảnh trong thư viện bằng php và muốn hình ảnh đã được hiển thị, được trình duyệt lưu vào bộ nhớ cache, vì vậy tập lệnh php không phải xuất lại cùng một hình ảnh. Tất cả những gì tôi muốn là hình ảnh hiển thị nhanh hơn.

khi gọi một hình ảnh tôi làm như thế này:

<img src="showImage.php?id=601"> 

showImage.php -file làm:

$resultat = mysql_query(" 
    SELECT filename, id 
    FROM Media 
    WHERE id = '".$_GET['id']."' 
"); 
$data = mysql_fetch_assoc($resultat); 

... 

//Only if the user are logged in 
if(isset($_SESSION['user'])){ 
    header("Content-Type: image/jpeg"); 

    //$data['filename'] can be = dsSGKLMsgKkD3325J.jpg 
    echo(file_get_contents("images/".$data['filename']."")); 
} 
+0

Tôi không chắc chắn những gì bạn đang cố gắng để hoàn thành, từ câu hỏi ban đầu của bạn nó có vẻ như thể bạn đang tạo ra hình ảnh một cách nhanh chóng và muốn lưu trữ các hình ảnh được tạo vào lần tải đầu tiên và phân phối từ đĩa trên các lần tải tiếp theo. Bạn đang nói về bộ nhớ đệm của trình duyệt? –

+1

Tại sao bạn vẫn sử dụng tập lệnh PHP? – Gumbo

+0

Có, tôi muốn trình duyệt lưu hình ảnh. – Johan

Trả lời

4

Nếu bạn đang sử dụng php để kiểm tra xem người dùng có đăng nhập hay không trước khi xuất thông báo, thì bạn không muốn trình duyệt lưu hình ảnh.

Toàn bộ điểm lưu bộ nhớ cache là gọi máy chủ một lần và sau đó không bao giờ gọi lại. Nếu trình duyệt lưu trữ hình ảnh, nó sẽ không gọi máy chủ và tập lệnh của bạn sẽ không chạy. Thay vào đó, trình duyệt sẽ kéo hình ảnh của bạn từ bộ nhớ cache và hiển thị nó, ngay cả khi người dùng không còn đăng nhập. Đây có thể là một lỗ hổng bảo mật rất lớn.

+0

Hm, đó là một điểm tốt. Nhưng nó sẽ là OK để lưu trữ hình ảnh một giờ khó khăn. – Johan

+1

Thậm chí một giờ không an toàn, tất cả những gì xảy ra là hy vọng rằng tin tặc không cố gắng hack vào một thời điểm nhất định. Tuy nhiên, từ những gì tôi có thể thấy trên http://www.mnot.net/cache_docs/#SCRIPT, có vẻ như bạn có thể ép buộc xác thực bằng bộ nhớ đệm bằng cách sử dụng 'Cache-control: public, no-cache;' trong tiêu đề HTTP của bạn ('no-cache' không thực sự có nghĩa là không có bộ nhớ đệm; các tên hơi lệch). – Imagist

+3

Bạn vẫn có thể lưu bộ nhớ cache * và * để trình duyệt gọi máy chủ. Nó được gọi là xác thực bộ nhớ cache. Bạn thực hiện điều này bằng cách gửi 'Cache-control: private, must-revalidate' (riêng tư vì nó không nên được chia sẻ giữa người dùng) và một trong hai' Last-Modified' hoặc 'ETag' header. Sau đó, khi trình duyệt gửi 'If-Modified-Since' hoặc' If-None-Match' trả lời trạng thái '304' nếu không có gì thay đổi kể từ khi hình ảnh được tạo. – Kornel

48

Trước hết, nếu bạn đang sử dụng phiên, bạn phải vô hiệu hóa session_cache_limiter (bằng cách đặt nó thành none hoặc public). Tiêu đề nó gửi là khá xấu cho cache.

session_cache_limiter('none'); 

Sau đó gửi Cache-Control: max-age=number_of_seconds và tùy chọn tương đương Expires: tiêu đề.

header('Cache-control: max-age='.(60*60*24*365)); 
header('Expires: '.gmdate(DATE_RFC1123,time()+60*60*24*365)); 

Đối với năng bộ nhớ cache tốt nhất, gửi Last-Modified header và trả lời với tư cách 304 và cơ thể trống rỗng nếu trình duyệt sẽ gửi một phù hợp với If-Modified-Since tiêu đề.

header('Last-Modified: '.gmdate(DATE_RFC1123,filemtime($path_to_image))); 

Đối với ngắn gọn tôi đang lừa dối ở đây một chút (ví dụ không xác minh ngày), nhưng nó có giá trị chừng nào bạn không nhớ các trình duyệt giữ các tập tin được lưu trữ mãi mãi:

if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { 
    header('HTTP/1.1 304 Not Modified'); 
    die(); 
} 
+0

Có, tôi đang sử dụng 'phiên'. Hm, có vẻ như bạn nói là những gì tôi cần, nhưng tôi không hiểu làm thế nào để có được điều đó với nhau để làm việc mã. Làm cách nào để viết nếu tôi muốn trình duyệt lưu hình ảnh trong một năm? – Johan

+0

Cảm ơn rất nhiều, chiếc wokring hoàn hảo cho tôi thật tuyệt vời! cảm ơn cảm ơn thnaks! :) – ParisNakitaKejser

+0

Bit '' If-Modified-Since'' là "d'oh" hoặc "eureka!" thời điểm, tùy theo bạn thích! – Agamemnus

3

bạn có thể lưu trữ những hình ảnh được tạo ra trong một thư mục gọi là "showImage" để bạn sẽ nhúng chúng như thế này

<img src="showimage/601.jpg" /> 

Sau đó, bạn đặt một tập tin .htaccess trong thư mục rất tương tự mà sẽ gọi showImage.php? id = trong trường hợp tập tin không tồn tại, ví dụ:

<IfModule mod_rewrite.c> 
    RewriteEngine On 
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteRule ^(.*)\.jpg$ showImage.php?id=$1 [QSA,L] 
</IfModule> 

Chỉ cần đọc trong bình luận của bạn mà bạn muốn làm phía khách hàng bộ nhớ đệm: chỉ cần thiết lập các tiêu đề HTTP caching-liên quan theo http://www.mnot.net/cache_docs/


Xin lưu ý rằng truy vấn của bạn là dễ bị tổn thương để tiêm SQL, bởi vì bạn không khử trùng/thoát $ _GET [ 'id']: http://php.net/mysql_real_escape_string

0

Xin vui lòng không giải quyết hình ảnh là một số tài nguyên id'ed. sử dụng url tuyệt đối cho hình ảnh, tốt nhất là trong tên miền phụ, tốt hơn là cookie ít hơn. Trình duyệt sẽ làm bộ nhớ đệm trên hình ảnh. Một mẹo nhỏ gọn để tải hình ảnh nhanh hơn trên các trang web là đặt nó trên một số CDN hoặc trang web khác. Điều này bởi vì trình duyệt giới hạn số chuỗi yêu cầu song song cho một miền.

Một cách gọn gàng khác để làm việc với hình ảnh là làm nổi bật, tra cứu. Nó tiết kiệm rất nhiều băng thông và cũng yêu cầu.

Bạn cũng có thể sử dụng tải bitmap trực tiếp nếu tốc độ quá quan trọng.Điều này không được khuyên dùng cho những hình ảnh lớn. Nếu biểu tượng của nó và hình ảnh/gif nhỏ mà bạn đang tải. Bạn có thể sử dụng bitmap trực tiếp trên trang.

7

Dưới đây là một số mã tôi sử dụng để hỗ trợ 304 tiêu đề:

/** 
    * @return false if not cached or modified, true otherwise. 
    * @param bool check_request set this to true if you want to check the client's request headers and "return" 304 if it makes sense. will only output the cache response headers otherwise. 
    **/  
    protected function sendHTTPCacheHeaders($cache_file_name, $check_request = false) 
    { 
    $mtime = @filemtime($cache_file_name); 

    if($mtime > 0) 
    { 
     $gmt_mtime = gmdate('D, d M Y H:i:s', $mtime) . ' GMT'; 
     $etag = sprintf('%08x-%08x', crc32($cache_file_name), $mtime); 

     header('ETag: "' . $etag . '"'); 
     header('Last-Modified: ' . $gmt_mtime); 
     header('Cache-Control: private'); 
     // we don't send an "Expires:" header to make clients/browsers use if-modified-since and/or if-none-match 

     if($check_request) 
     { 
     if(isset($_SERVER['HTTP_IF_NONE_MATCH']) && !empty($_SERVER['HTTP_IF_NONE_MATCH'])) 
     { 
      $tmp = explode(';', $_SERVER['HTTP_IF_NONE_MATCH']); // IE fix! 
      if(!empty($tmp[0]) && strtotime($tmp[0]) == strtotime($gmt_mtime)) 
      { 
      header('HTTP/1.1 304 Not Modified'); 
      return false; 
      } 
     } 

     if(isset($_SERVER['HTTP_IF_NONE_MATCH'])) 
     { 
      if(str_replace(array('\"', '"'), '', $_SERVER['HTTP_IF_NONE_MATCH']) == $etag) 
      { 
      header('HTTP/1.1 304 Not Modified'); 
      return false; 
      } 
     } 
     } 
    } 

    return true; 
    } 
Các vấn đề liên quan