Zřejmě každý začínající PHP vývojář se jednou setká s problémem jak vytvořit možnost stažení souboru aniž by uživatel měl možnost vidět přesnou adresu odkud soubor stahuje. Toto a spoustu dalších výhod nabízí jednoduchá funkce, kterou naleznete v článku.
<?php
function force_download ($data, $name, $mimetype='', $filesize=false) {
// File size not set?
if ($filesize == false OR !is_numeric($filesize)) {
$filesize = strlen($data);
}
// Mimetype not set?
if (empty($mimetype)) {
$mimetype = 'application/octet-stream';
}
// Ujistíme se, že v souboru nejsou data navíc
ob_clean_all();
// Odeslání hlavičky
header("Pragma: public"); // požadováno
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); // požadováno u některých prohlížečů
header("Content-Transfer-Encoding: binary");
header("Content-Type: " . $mimetype);
header("Content-Length: " . $filesize);
header("Content-Disposition: attachment; filename="" . $name . "";" );
// Finální odeslání souboru
echo $data;
die();
}
function ob_clean_all () {
$ob_active = ob_get_length () !== false;
while($ob_active) {
ob_end_clean();
$ob_active = ob_get_length () !== false;
}
return true;
}
?>
Pro ty z vás co nejste zvyklí na použití vlastních definovaných funkcí, napíšu jednoduchý návod jak na to.
'hqx' => 'application/mac-binhex40',
'cpt' => 'application/mac-compactpro',
'csv' => array('text/x-comma-separated-values', 'application/vnd.ms-excel'),
'bin' => 'application/macbinary',
'dms' => 'application/octet-stream',
'lha' => 'application/octet-stream',
'lzh' => 'application/octet-stream',
'exe' => 'application/octet-stream',
'class' => 'application/octet-stream',
'psd' => 'application/x-photoshop',
'so' => 'application/octet-stream',
'sea' => 'application/octet-stream',
'dll' => 'application/octet-stream',
'oda' => 'application/oda',
'pdf' => array('application/pdf', 'application/x-download'),
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
'smi' => 'application/smil',
'smil' => 'application/smil',
'mif' => 'application/vnd.mif',
'xls' => array('application/excel', 'application/vnd.ms-excel'),
'ppt' => 'application/powerpoint',
'wbxml' => 'application/wbxml',
'wmlc' => 'application/wmlc',
'dcr' => 'application/x-director',
'dir' => 'application/x-director',
'dxr' => 'application/x-director',
'dvi' => 'application/x-dvi',
'gtar' => 'application/x-gtar',
'gz' => 'application/x-gzip',
'php' => 'application/x-httpd-php',
'php4' => 'application/x-httpd-php',
'php3' => 'application/x-httpd-php',
'phtml' => 'application/x-httpd-php',
'phps' => 'application/x-httpd-php-source',
'js' => 'application/x-javascript',
'swf' => 'application/x-shockwave-flash',
'sit' => 'application/x-stuffit',
'tar' => 'application/x-tar',
'tgz' => 'application/x-tar',
'xhtml' => 'application/xhtml+xml',
'xht' => 'application/xhtml+xml',
'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'),
'mid' => 'audio/midi',
'midi' => 'audio/midi',
'mpga' => 'audio/mpeg',
'mp2' => 'audio/mpeg',
'mp3' => 'audio/mpeg',
'aif' => 'audio/x-aiff',
'aiff' => 'audio/x-aiff',
'aifc' => 'audio/x-aiff',
'ram' => 'audio/x-pn-realaudio',
'rm' => 'audio/x-pn-realaudio',
'rpm' => 'audio/x-pn-realaudio-plugin',
'ra' => 'audio/x-realaudio',
'rv' => 'video/vnd.rn-realvideo',
'wav' => 'audio/x-wav',
'bmp' => 'image/bmp',
'gif' => 'image/gif',
'jpeg' => array('image/jpeg', 'image/pjpeg'),
'jpg' => array('image/jpeg', 'image/pjpeg'),
'jpe' => array('image/jpeg', 'image/pjpeg'),
'png' => array('image/png', 'image/x-png'),
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'css' => 'text/css',
'html' => 'text/html',
'htm' => 'text/html',
'shtml' => 'text/html',
'txt' => 'text/plain',
'text' => 'text/plain',
'log' => array('text/plain', 'text/x-log'),
'rtx' => 'text/richtext',
'rtf' => 'text/rtf',
'xml' => 'text/xml',
'xsl' => 'text/xml',
'mpeg' => 'video/mpeg',
'mpg' => 'video/mpeg',
'mpe' => 'video/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
'avi' => 'video/x-msvideo',
'movie' => 'video/x-sgi-movie',
'doc' => 'application/msword',
'word' => array('application/msword', 'application/octet-stream'),
'xl' => 'application/excel',
'eml' => 'message/rfc822'
Uvedu jednoduchý příklad. Máte webový projekt, kde nabízíte soubory komisním prodejem. Uživatel si zaplatí za jeden soubor a vy mu poskytnete url na které si může požadovaný soubor stáhnout. Tato url může vypadat následovně:
http://stranka.cz/cesta/k/ulozenemu/souboru.zip
Prostý uživatel si soubor stáhne a je spokojen. Ovšem zaběhlejšímu uživatelovi už ale může dojit, že v tom samém adresáři budou zřejmě uložené i ostatní soubory a začne tipovat názvy ostatních. A profík už si jednoduše zjistí podle čeho je konkrétní název odvozen a už stahuje celkem na jisto. Samozřejmě lze název zakódovat do md5 atd., ale to už mi nepřijde jako zrovna „elegantní“ řešení.
http://stranka.cz/download.php?soubor={id_souboru}
Tímto způsobem nedáte uživateli žádnou možnost aby zjistil odkud
soubor pochází. A pokud jste ještě více paranoidní, tak můžete místo
id použít třeba již výše zmíněný zakódovaný string.
Toto řešení mi přijde nejlepší jak z bezpečnostního hlediska, tak
i z hlediska usnadnění práce a to se přece taky počítá ne?
http://stranka.cz/download.php?soubor={id_souboru}
uziv pak netypuje nazvy souboru, ale id.
Je treba dodat, ze se pak musi kontrolovat, zda ma uziv k tomuto id pravo (muze ho stahovat)
Je to pojaté univerzálně a tímto stylem lze opravdu ochranu před nevyžádaným stážením ošetřit mnoha způsoby. Jedním z nich je třeba ten co zmiňujete…
header(„Content-Type: " . $mimetype); header(“Content-Length: " . $filesize); header(„Content-Disposition: attachment; filename="" . $name . "";“ );
opravit
Diky za clanek
soubor jpg se mi stahne jako php php stažení soubor download.php php stažení souboru místo souboru avi videa soubor txt php stahnout soubor header application/octet-stream application/force stažení php souboru octet stream php force download octet-stream stažení souboru php download souboru php stazeni souboru header mime type: application/octet-stream php download souboru php odeslání souboru pdf stažení souboru přes header