PHP ve MySQL kullanarak resized görüntüleri önbelleğe için en iyi yol

9 Cevap php

Ne PHP kullanarak görüntülerin önbelleğe işlemek için en iyi uygulama yolu olacaktır.

Dosya şu anda orijinal dosya ve alt etiketi ile birlikte, yükleme bir GUID değiştirildi MySQL veritabanında saklanır.

Görüntü HTML sayfaları içine konulduğu zaman o yüzden böyle bir php komut dosyası yeniden yazılıyor '/ images/get/200x200 / {guid}. Jpg gibi bir url kullanarak yapılır. Dosya boyutu - Bu benim tasarımcıları (kaynak görüntüyü belki daha küçük kabaca) belirlemenizi sağlar.

Php komut dosyası daha sonra boyut (url 200x200) ve GUID dosya karmasını oluşturur ve dosya (TMP dizininde zaten karma adıyla dosyası) daha önce üretilmiş olup olmadığını uygulama TMP dizinine dosyayı gönderir. Karma dosya yoksa, o zaman, oluşturulan diske yazılır ve aynı şekilde yukarı servis edilir

Bu olabildiği kadar verimli mi? (Ayrıca görüntüleri ve filigran ayarlarını da karma saklanır filigran destekler, ancak bunun için kapsam dışında şu.)

9 Cevap

Orada Dan Udey en rewrite örnekte iki yazım hataları (ve ben yorum yapamam), oldukça olmalıdır:

RewriteCond %{REQUEST_URI} ^/images/cached/
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule (.*) /images/generate.php?$1 [L]

Saygılar.

Ben farklı bir şekilde yapardı.

Problems: 1. Having PHP serve the files out is less efficient than it could be. 2. PHP has to check the existence of files every time an image is requested 3. Apache is far better at this than PHP will ever be.

Bir kaç çözüm var burada.

Sen mod_rewrite Apache üzerinde kullanabilirsiniz. Bu bir dosya olup olmadığını görmek için test etmek için mod_rewrite kullanmak mümkün, ve eğer öyleyse, bunun yerine bu dosyayı hizmet. Bu tamamen PHP atlar ve işler çok daha hızlı yapar. Bunu yapmak için gerçek yolu olsa da, her zaman bulunması gereken belirli bir URL şeması oluşturmak, ve sonra PHP değilse yönlendirmek olacaktır.

Örneğin:

RewriteCond %{REQUEST_URI} ^/images/cached/
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule (.*) /images/generate.php?$1 [L]

Bir istemci istekleri /images/cached/<something> ve bu dosya zaten mevcut değilse Yani, Apache /images/generate.php?/images/cached/<something> isteği yönlendirir. Bu komut dosyası daha sonra, görüntü oluşturabilir bu önbellek yazma, ve sonra müşteri göndermek. Gelecekte, PHP komut dosyası yeni görüntüler dışında asla denir.

Önbelleğe kullanın. Başka bir poster dediği gibi, koşullu GET isteklerine yanıt vb mod_expires gibi şeyler, Son-Modifiye başlıkları kullanın. Istemci yeniden talep görüntüleri yoksa, sayfa yükler önemli ölçüde hızlandıracaktır ve sunucu üzerinde yük azalacak.

Eğer PHP bir görüntü göndermek zorunda durumlar için, mod_xsendfile daha az yük ile bunu yapmak için kullanabilirsiniz. the excellent blog post from Arnold Daniels konuda bkz, ancak onun örnek yüklemeler için olduğunu unutmayın. (Üçüncü başlık () çağrısı) Content-Disposition başlığını çıkarıp, satır içi görüntüleri hizmet etmek.

Umarım bu yardımcı olur - benim migren kadar temizler daha sonra.

Ekleyerek değer bir not kod, bu görüntülerin "yetkisiz" boyutlarda üretmek değil mi emin olmaktır.

Biri zaten yoksa Yani aşağıdaki URL görüntünün 1234 bir 200x200 sürümünü oluşturmak olacaktır. I highly Eğer istenen URL desteklemek görüntü boyutlarını içerdiğinden emin olun öneririm.

/images/get/200x200/1234.jpg

Kötü niyetli bir kişi her zaman yüksekliğini değiştirerek, rasgele URL'leri talep başlayabilirsiniz & olabilir Görüntünün genişliği. Bu sizi desteklemeyen boyutlarda görüntüler üreten, aslında saldırı altında, orada oturan olacak b / c sunucuyu bazı ciddi sorunlara neden olur.

/images/get/0x1/1234.jpg
/images/get/0x2/1234.jpg
...
/images/get/0x9999999/1234.jpg
/images/get/1x1/1234.jpg
...
etc

İşte bu gösteren bir kod rastgele kelepir bulunuyor:

<?php

    $pathOnDisk = getImageDiskPath($_SERVER['REQUEST_URI']);

    if(file_exists($pathOnDisk)) {
        // send header with image mime type 
        echo file_get_contents($pathOnDisk);
        exit;
    } else {
        $matches = array();
        $ok = preg_match(
            '/\/images\/get\/(\d+)x(\d+)\/(\w+)\.jpg/', 
            $_SERVER['REQUEST_URI'], $matches);

        if(! $ok) {
            // invalid url
            handleInvalidRequest();
        } else {
            list(, $width, $height, $guid) = $matches;

            // you should do this!
            if(isSupportedSize($width, $height)) {
                // size is supported. all good
                // generate the resized image, save it & output it
            } else {
                // invalid size requested!!!
                handleInvalidRequest();
            }
        }
    }

    // snip
    function handleInvalidRequest() {
        // do something w/ invalid request          
        // show a default graphic, log it etc
    }
?>

Büyük bir mesaj görünüyor, ama benim sorun hala çözülememiştir. Benim ana sağlayıcı htaccess erişimi yok, bu yüzden apache verdiği hiçbir soru. Görüntüler için CACE kontrol başlığı ayarlamak için bir yol gerçekten var mı?

Sizin yaklaşım oldukça makul görünüyor - önbelleğe / resized sürümünü yeniden değilse bazı mekanizması önbelleğe sürümü oluşturulduğu tarih, orijinal (kaynak) görüntü dosyasının son değiştirilme damgası sonra olduğunu kontrol etmek yerine koymak gerektiğini eklemek istiyorum . Bu bir görüntü tasarımcılar tarafından değiştirilirse önbellek uygun biçimde güncellenecektir sağlayacaktır.

İşte bunu yapmak için sağlam bir yol gibi geliyor. Bir sonraki adım, PHP / MySQL ötesine gitmek olabilir.

Belki de, tweak your headers:

MIME türlerini göndermek için PHP kullanıyorsanız, ayrıca sunucuda görüntülerin ömrünü uzatmak ve PHP / MySQL kapalı yük bazı almak için 'Keep-canlı' ve 'Cache-control' başlıklarını kullanabilirsiniz.

Ayrıca, aynı zamanda önbelleğe alma için apache eklentisi (ler) düşünün. Gibi mod_expires.

Ah, bir şey daha, size sunucu üzerinde ne kadar kontrol var mı? Biz just PHP / MySQL bu konuşmayı sınırlamak gerekir?

phpThumb anında resized images / küçük resimler üretir bir çerçevedir. Ayrıca önbelleğe uygulayan ve uygulamak çok kolay.

The code to resize an image is: <img src="/phpThumb.php?src=/path/to/image.jpg&w=200&h=200" alt="thumbnail"/> will give you a thumbnail of 200 x 200;

Ayrıca, damgalama destekler.

Check it out at: http://phpthumb.sourceforge.net/

Ben sadece PHP bir yönlendirme başlığı kullanarak bunu başardınız:

if (!file_exists($filename)) {  

    // *** Insert code that generates image ***

    // Content type
    header('Content-type: image/jpeg');	

    // Output
    readfile($filename);	

} else {
    // Redirect
    $host  = $_SERVER['HTTP_HOST'];
    $uri   = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
    $extra = $filename;
    header("Location: http://$host$uri/$extra");
}

? Image/picture_1234.png rnd = 6534122341: yerine db dosya adresini tutmak ben dosya adının her kullanıcı, 1234 böyle bir şey içeri kullanıcı günlükleri için rastgele bir sayı ekleyerek tercih ederim

Kullanıcı oturumu sırasında yeni bir resim gönderir, ben sadece rastgele sayı yenileyin.

GUID önbellek sorunu% 100 ele almaktadır. Ancak tür zor resim dosyalarını takip etmek için yapar. Bu yöntem ile kullanıcının gelecekteki bir oturum yine aynı resmi görebilirsiniz bir şans var. Bir milyar numaraları rastgele sayı üretmek Ancak oran düşüktür.