Zdravím, potřebuji na stránky umístit pár souborů ke stažení. Chtěl bych to udělat dynamicky, script projede adresář, vypíše jména souborů a přidá ikonu podle typu. Je něco na co si dát velký pozor? Nebo je lepší to řešit staticky?
Fórum › PHP
Download seznam
#1 Pavelv
Zde opět vede mapa - přiřaď typům obrázky -> v asociativním poli.
data.php
$fileTypeMap = array("png" => "icon7.jpg");
ddd.php
$files = scandir("forDownload");
foreach($files as $file)
{
$img = $fileTypeMap[pathinfo($file, PATHINFO_EXTENSION)];
$fileName = pathinfo($file, PATHINFO_BASENAME);
echo <<<END
<a href="download.php?file=$fileName">$fileName</a>
<img alt="..." src="$img" ... />
END;
}
CCA. takto bych to dělal já. A když-tak bych tam nastrkal AJAX...
#3 Pavelv
Vemte téma z UNIXu/Linuxu (tam je téměř jen OpenSource SW) - třeba Tango:
http://tango.freedesktop.org/releases/tango-icon-theme-0.8.90.tar.gz
(Říká se tomu mimetype, pročež vše najdete ve složce velikost -> mimetypes. Příklad: "32x32\mimetypes")
BTW:
Rozbalí to třeba 7z - prvně GZIP, pak TAR.
#5 Pavelv
AJAX na to PHP, které zajistí stažení. (download.php) Ideál je, když navíc balí adresáře do archivů atp. Tedy ono PHP na zajištění stahování vydá na základě QueryStringu stream souboru... (Otevřeš stream a pošleš ho do pohledu.) A co se týče vzhledu - být tebou netvrdím, že je něco hezčí. Každému libo je dle vůle a charakteru. Mě se Tango líbí a jak jsem psal - můžeš si projít i dalši "icon theme" ze zmíněného prostředí.
BTW - QueryString jsem ti ukázal zde:
<a href="download.php?file=$fileName">$fileName</a>
#6 Matěj Andrle
Zjistil jsem že to jde i bez AJAXu:
$filename = $_GET['file'];
$mimeTypes = array(
'pdf' => 'application/pdf',
'txt' => 'text/plain',
'html' => 'text/html',
'exe' => 'application/octet-stream',
'zip' => 'application/zip',
'doc' => 'application/msword',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
'gif' => 'image/gif',
'png' => 'image/png',
'jpeg' => 'image/jpg',
'jpg' => 'image/jpg',
'php' => 'text/plain'
);
$fileExt = pathinfo($filename, PATHINFO_EXTENSION);
if(array_key_exists($fileExt, $mimeTypes)) {
$mimeType = $mimeTypes[$fileExt];
}
else {
$mimeType = 'application/force-download';
}
header('Content-Description: File Transfer');
header('Content-Type: '.$mimeType);
header('Content-Disposition: attachment; filename="'. basename($filename) . '";');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Cache-Control: private', false); // required for certain browsers
header('Content-Length: '.filesize($filename));
ob_clean();
flush();
readfile($filename);
exit;
Jak bych měl ošetřit vstupní část, aby nebylo možné zavítat do jiné složky? Stačí najít lomítka a ty odstranit?
#8 Matěj Andrle
Na těch pár MIME je skoro zbytečné takový datový soubor dělat. Stačí, když to uzavře do funkce nebo objektu. Netvrdím, že je to ideální řešení, ale mně se líbí:
<?php
function getMime($fileExt) {
switch ($fileExt) {
case 'pdf': return 'application/pdf';
case 'txt': return 'text/plain';
case 'html': return 'text/html';
case 'exe': return 'application/octet-stream';
case 'zip': return 'application/zip';
case 'doc': return 'application/msword';
case 'xls': return 'application/vnd.ms-excel';
case 'ppt': return 'application/vnd.ms-powerpoint';
case 'gif': return 'image/gif';
case 'png': return 'image/png';
case 'jpeg': return 'image/jpeg';
case 'jpg': return 'image/jpeg';
case 'php': return 'text/plain';
}
return 'application/force-download';
}
$fileExt = pathinfo($filename, PATHINFO_EXTENSION);
$mimeType = getMime($fileExt);
nebylo by jednodussi zapnout u konkretniho adresare DirectoryIndex a nesrat se s tim v php, kdyz tam nepotrebuje zadny vychytavky jako omezeni pristupu (coz by taky zvladl http server)?
#14 Pavelv
Jít by to nemělo už jen z logiky - to by pak byly všechny servery zcela bezbranné... Máš tedy blbě nastavený server - jak jsem psal, prostě to nastav tak, aby se nedaly soubory stahovat - vůbec. Pak to půjde jen zevnitř PHP scriptu, který si soubory otevře a jejich proud pošle do pohledu...
#15 Matěj Andrle
Tomu nerozumím. Script na serveru přece má oprávnění pro otevírání dalších souborů souborů(include, require,..) To, že se daný script pak již nekompiluje ale zobrazuje rovnou uživateli má už na starosti právě obslužný script. Kde bych měl takové procházení zakázat? Uživatel zvenku se tam nedostane, díky direktivě Options -Indexes v .htaccess
#14 Pavelv
Vytvořil sis klasickou bezpečnostní díru. Musíš si nejprve obsloužit, zda má uživatel právo ten soubor stáhnout. Nejlépe pokud odstraníš všechny cesty, které jsou před názvem souboru. Dáš pak před něj název adresáře, kam ten uživatel smí. Jinam se už nedostane.
Já tuto situaci nechápu. Pokud jde o pár souborů, pak přeci stačí list povolených souborů a zbytek jak jsem psal...
#18 Pavelv
Určitě dej nahrávané soubory do samostatného adresáře, např. "downloads". Skript pak bude vypadat asi takto:
<?php
$filename = 'downloads/' . basename($_GET['file']);
$fileExt = pathinfo($filename, PATHINFO_EXTENSION);
$mimeType = getMime($fileExt);
header('Content-Type: ' . $mimeType);
header('Content-Length: ' . filesize($filename));
readfile($filename);
#21 Pavelv
Nechtělo se mi zkoumat, co ten tvůj regulár dělá, proto jsem použil standardní funkci basename().
Mít data pro uživatele odděleně je docela důležité. Také je důležité, aby skripty uložené do tohoto adresáře nebylo možné spustit.
Zajímavou variantou by mohlo být uložení do databáze, ale to se hodí spíš pro malé soubory.
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Download — založil Jakub Vojáček
Moderátoři diskuze