SORU
13 EYLÜL 2010, PAZARTESİ


Hızlı bir Dosya PHP Kullanarak Hizmet edecek Şekilde

Birlikte bir dosya yolu alır, ne olduğunu tanımlar, ilgili başlıkları ayarlar ve Apache gibi sadece hizmet eden bir işlev koymak için çalışıyorum.

Ben bunu yapıyorum neden PHP dosya hizmet öncesi isteği hakkında bazı bilgileri işlemek için kullanmak istiyorum çünkü.

Hız önemlidir

() sanal bir seçenek değil

Kullanıcı web server (Apache/nginx, vb.) hiçbir kontrole sahip olduğu paylaşılan bir barındırma ortamında çalışmak zorundadır

Şimdiye kadar var:

File::output($path);

<?php
class File {
static function output($path) {
    // Check if the file exists
    if(!File::exists($path)) {
        header('HTTP/1.0 404 Not Found');
        exit();
    }

    // Set the content-type header
    header('Content-Type: '.File::mimeType($path));

    // Handle caching
    $fileModificationTime = gmdate('D, d M Y H:i:s', File::modificationTime($path)).' GMT';
    $headers = getallheaders();
    if(isset($headers['If-Modified-Since']) && $headers['If-Modified-Since'] == $fileModificationTime) {
        header('HTTP/1.1 304 Not Modified');
        exit();
    }
    header('Last-Modified: '.$fileModificationTime);

    // Read the file
    readfile($path);

    exit();
}

static function mimeType($path) {
    preg_match("|\.([a-z0-9]{2,4})$|i", $path, $fileSuffix);

    switch(strtolower($fileSuffix[1])) {
        case 'js' :
            return 'application/x-javascript';
        case 'json' :
            return 'application/json';
        case 'jpg' :
        case 'jpeg' :
        case 'jpe' :
            return 'image/jpg';
        case 'png' :
        case 'gif' :
        case 'bmp' :
        case 'tiff' :
            return 'image/'.strtolower($fileSuffix[1]);
        case 'css' :
            return 'text/css';
        case 'xml' :
            return 'application/xml';
        case 'doc' :
        case 'docx' :
            return 'application/msword';
        case 'xls' :
        case 'xlt' :
        case 'xlm' :
        case 'xld' :
        case 'xla' :
        case 'xlc' :
        case 'xlw' :
        case 'xll' :
            return 'application/vnd.ms-excel';
        case 'ppt' :
        case 'pps' :
            return 'application/vnd.ms-powerpoint';
        case 'rtf' :
            return 'application/rtf';
        case 'pdf' :
            return 'application/pdf';
        case 'html' :
        case 'htm' :
        case 'php' :
            return 'text/html';
        case 'txt' :
            return 'text/plain';
        case 'mpeg' :
        case 'mpg' :
        case 'mpe' :
            return 'video/mpeg';
        case 'mp3' :
            return 'audio/mpeg3';
        case 'wav' :
            return 'audio/wav';
        case 'aiff' :
        case 'aif' :
            return 'audio/aiff';
        case 'avi' :
            return 'video/msvideo';
        case 'wmv' :
            return 'video/x-ms-wmv';
        case 'mov' :
            return 'video/quicktime';
        case 'zip' :
            return 'application/zip';
        case 'tar' :
            return 'application/x-tar';
        case 'swf' :
            return 'application/x-shockwave-flash';
        default :
            if(function_exists('mime_content_type')) {
                $fileSuffix = mime_content_type($path);
            }
            return 'unknown/' . trim($fileSuffix[0], '.');
    }
}
}
?>

CEVAP
16 EYLÜL 2010, PERŞEMBE


Önceki cevabımı kısmi ve işte bu da başkalarından gelen ve çözümleri özeti bir güncelleme tartışmada belgelenmiş değil.

Çözümlerin en iyi çözüm, en kötü ama aynı zamanda çözüm için bir web sunucusu ihtiyacı üzerinde daha az kontrol ihtiyacı sıralanmıştır. Hızlı ve her yerde işe de bir çözüm var kolay bir yolu yok.


X-SendFile Başlığı kullanarak

Başkaları tarafından belirtildiği gibi, aslında en iyi yolu budur. Temel php access kontrol yapın ve sonra dosyayı kendiniz göndermek yerine web sunucusu bunu söyleyin.

Temel php kodu :

header("X-Sendfile: $file_name");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($file_name) . '"');

$file_name * * * * dosya sistemi üzerinde tam yoludur.

Asıl sorun bu çözüm bu ihtiyaç için izin web sunucusu ya da değil yüklü varsayılan (apache), değil etkin varsayılan (lighttpd) veya bir özel yapılandırma (nginx).

Apache

Eğer mod_php kullanırsanız apache altında bir modül mod_xsendfile yapılandırma (apache ya da config veya .adlı yüklemeniz gerekir eğer izin verirseniz debug)

XSendFile on
XSendFilePath /home/www/example.com/htdocs/files/

Bu modül ile dosya yolu mutlak veya XSendFilePath belirtilen akraba olabilir.

Lighttpd

Bu mod_fastcgi ile yapılandırıldığında bu destek

"allow-x-send-file" => "enable" 

Özelliği belgelerine lighttpd wiki onlar X-LIGHTTPD-send-file Başlığı belgedir ama X-Sendfile adı da çalışır

Nginx

Nginx X-Accel-Redirect adlı kendi başlığını kullanmanız gerekir. X-Sendfile Başlığı kullanabilirsiniz. Varsayılan olarak etkinleştirilir ve tek fark bu bağımsız değişken bir URI dosya sistemi olmalıdır. Sonuç olarak bir yerde iç olarak işaretlenmiş yapılandırmanızı müşterilerine gerçek dosya url bulmak ve onu doğrudan önüne geçmek tanımlamalısınız, bu wiki a good explanation içerir.

Sembolik ve Konum başlık

symlinks kullanabilirsiniz ve onlar için, sadece bir kullanıcı dosya erişim ve kullanıcı kullanarak yönlendirmek için izin verildiğinde rastgele adları ile dosyaya sembolik bağ oluşturur yönlendirme:

header("Location: " . $url_of_symlink);

Belli ki onları oluşturmak için komut dosyası adı veya cron ile onları da budamak için bir yol (bazı webcron hizmeti yoksa) eğer erişim varsa makinede yoksa) gerekir

Apache altında ** 29 veya apache config FollowSymLinks etkinleştirmek için gerekir.

IP ve Konum bilgisi tarafından kontrol erişim

Başka bir hack php apache erişim dosyaları açık kullanıcı IP izin oluşturmaktır. Apache altındamod_authz_host (mod_access) Allow from komutları kullanarak.

Sorun dosya kilitleme erişim birden çok kullanıcının aynı anda yapmak istiyor ya da önemsiz olmayan ve bazı kullanıcılar uzun bir süre bekliyor neden olabilir. Ve sen hala bu dosya zaten budamak gerekir.

Belli ki başka bir sorun aynı IP arkasında birden fazla kişi dosya erişim olabilecek.

Diğer her şey başarısız olduğunda

Eğer gerçekten yok herhangi bir şekilde almak için web sunucusu için yardım, tek çözüm kalan readfile mevcut tüm php sürümleri kullanılmakta ve çalışması oldukça iyi (ama değil gerçekten verimli).


Çözümleri birleştirerek

İyi, en iyi şekilde göndermek bir dosyayı çok hızlı istiyorsan php kodu için kullanılabilir her yerde bir yapılandırılabilir seçenek bir yerlerde, talimatlar nasıl aktive etmesi için bağlı web sunucusu ve belki de bir otomatik algılama içinde yükleme komut.

Yazılım bir çok yer için ne yapılır için oldukça benzer

  • URL (apachemod_rewrite) temizleyin
  • Kripto fonksiyonları (mcrypt php modülü)
  • Boş dize destek (mbstring php modülü)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • BigDawsVlogs

    BigDawsVlogs

    17 HAZİRAN 2013
  • How To Cook That

    How To Cook

    16 NİSAN 2011
  • ShayLoss

    ShayLoss

    5 Kasım 2009