PHP kullanarak. Jpg dosyası için bir download linki oluşturma

5 Cevap php

Bu kolay bir olmalı, diye düşünüyorum. Ben bir paginated resim galerisi var, ve her bir görüntünün altında "Zorunlu indirin" diyor küçük bir bağlantıdır. Bu, insanların hızlı bir şekilde bilgisayarınıza (PHP oluşturulan filigran ile). Jpg dosyasını indirmek için izin vermelidir.

Şimdi, ben sadece. Jpg dosyasına düz bağlantı biliyorum, ama bu doğru ben "Zorunlu indirin" istiyorum, yerine, Save As ... vb tıklayın, yeni bir pencerede aç imaja sahip kullanıcı gerektirir hemen dosya yüklemeyi başlatmak için bağlantı.

PHP.net readfile () kullanarak önermek gibiydi, böylece her "Zorunlu indirin" link "? Indir = true & g = {$ gallery} & i = {$ image}" olarak yankılandı ediliyor.

Sonra sayfanın üstünde görmeyi yakalamak eğer $ _GET ['download'] var isset, ve eğer öyleyse, ben aşağıdaki kodu çalıştırın:

if(isset($_GET['download'])) {
$gallery = $_GET['g'];
$image = $_GET['i'];
$file = "../watermark.php?src={$gallery}/images/{$image}";
header('Content-Description: File Transfer');
    header('Content-Type: application/jpeg');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: public');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
readfile($file);

}

Bağlantı lonnnnnnnnng zaman alır, ve sonra bu dosyayı açmak veya kaydetmek isteyen bir iletişim istemi getirir, ama kaydedin ve açmayı deneyin bir kez, o dosya bozuk ve açılamaz diyor.

Herhangi bir fikir?

5 Cevap

$ Dosya göreli bir url koymayın. Readfile işlevi sunucudaki php dosyasına erişmeye çalışacaktır. Ne istediğiniz değil. Senin durumunda watermark.php dosyaya istediğiniz içeriği göndermek olacak gibi görünüyor, bu yüzden muhtemelen sadece ihtiyacı ortamı kurmak ve onu içerebilir.

<?php
if(isset($_GET['download'])) {
    $gallery = $_GET['g'];
    $image = $_GET['i'];
    $_GET['src'] = "{$gallery}/images/{$image}";

    header('Content-Description: File Transfer');
    header('Content-Type: image/jpeg');
    header('Content-Disposition: attachment; filename='.basename($image));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: public');
    header('Pragma: public');
    ob_clean();
    include('../watermark.php');
    exit;
}

Başka bir (basit) yolu watermark.php değiştirmek için. O bir indirme ve bağlantı zorlamak için uygun başlıklarını göndermek yapmak için bir sorgu parametresi ekleyin

<a href="watermark.php?src=filename.jpg&download=true)">...</a>

watermark.php:

<?php
if (isset($_GET['download']) && $_GET['download'] == 'true') {
    header('Content-Description: File Transfer');
    header('Content-Type: image/jpeg');
    header('Content-Disposition: attachment; filename='.basename($src));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: public');
    header('Pragma: public');
}
// continue with the rest of the file as-is

Ayrıca, () temizlemek için çağrı gerekmez. Orada bu noktada göndermek için herhangi bir çıkış olmayacak, bu nedenle gerekli değildir gerekir.

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

Belki?

Bu bir güvenlik sorunu gibi görünüyor.

Ya birisi girerse:

$g = '../../../../../../';
$i = '../../sensitive file at root';

(Eğer apache kullanıyorsanız). Htaccess yapma konusunda i galeri dizinde için oldukça normal bir yükleme olarak jpegler kadar hizmet nasıl.

Sana exit() emin başka bir şey çıktı tamponuna yazılı alır yapmak için bir çağrı ile readfile() için çağrı takip gerekebilir düşünüyorum.

Ayrıca, file_get_contents() yerine readfile() deneyin. Ben daha çok şartlar altında çalışıyor bulabilirsiniz. Ben aynı zamanda size çıktı görüntü verisi ob_flush() kullanmanızı tavsiye ederim. Ben çalışmak için bu tür bir şey almak için ob_clean() veya flush() kullanmak için gereken hiç ettik.

Dedi Eric gibi, siz de hala sadece durumda sonunda sıkışmış bazı önemsiz verileri alıyorsanız çalışma değilse iyi ölçmek için de orada exit() için bir çağrı koymak isteyebilirsiniz.