Napewno niejednokrotnie chcia艂e艣 udost臋pni膰 na stronie u偶ytkownikom pliki do pobrania, jednak nie chcia艂e艣, aby wiedzieli oni w jakich katalogach si臋 te pliki znajduj膮 oraz jakie maj膮 oryginalne nazwy. Problem na poz贸r do艣膰 trudny do rozwi膮zania. Na poz贸r, poniewa偶 przy znajomo艣ci podstaw PHP i przeczytania tego postu (nie b臋d臋 wnika艂 w stopie艅 zrozumienia tekstu) oka偶e si臋 to niezwykle proste. W niekt贸rych przypadkach wykorzystanie tego przyk艂adu mo偶e by膰 niewygodne. Zatem zach臋cam do wprowadzania modyfikacji na w艂asn膮 r臋k臋.
Oczywi艣cie aby co艣 pobra膰 nale偶y klikn膮膰 w link umieszczony na stronie, nie b臋d臋 si臋 w tej kwesti wy艂amywa膰 i zaczn臋聽od linka:
| http://itblog.e-czluchow.com.pl/download.php?id=813881e6e9f1db&filename=phpman.pdf |
O prosz臋, i tak wygl膮da adres odno艣nika. Niebardzo wiadomo co i sk膮d. Mo偶esz si臋 ze mn膮聽nie zgodzi膰, bo przecie偶 wiesz, 偶e pobierasz plik “phpman.pdf”. Poniek膮d mo偶e i masz racj臋, a mo偶e i nie. Tak naprade “phpman.pdf” pos艂u偶y nam tylko jako dowolna warto艣膰 zmiennej filename, kt贸ra po klikni臋ciu w link zostanie umieszczona w polu “Nazwa pliku” okienka “Pobierania pliku”. Reasumuj膮c nie ma najmniejszego znaczenia czy zmienna filename przyjmi臋 warto艣膰 “phpman.pdf” czy “abc123.bcd”. Zalety takiej metody s膮 chyba oczywiste, poza nieujawnianiem u偶ytkownikom zb臋dnych informacji uniemo偶liwiamy ingerencj臋 w zawarto艣膰 naszego katalogu. Jest to bardzo przydatne kiedy mamy katalog z uprawnieniami 777 (czyt. -rwx-rwx-rwx), do kt贸rego uploadowane s膮 pliki.
Dalej kolej na zawarto艣膰 pliku download.php, kt贸ra w moim przypadku wygl膮da tak:
| <? $fpath = ‘/upload/freeware/’.$id; $fp=fopen($fpath,’r'); $size=filesize($fpath); header(”Content-Disposition: attachment; filename=$filename”); header(’Content-Type: application’); header(’Content-Length:’.$size); fpassthru($fp); fclose($fp); ?> |
Wyja艣nienie kodu.
| $fpath = ‘/upload/freeware/’.$id; |
przypisuje do zmiennej “path” pe艂n膮 艣cie偶k臋聽do pliku, kt贸ry ma zosta膰 pobrany; i tutaj niespodzianka! jak si臋 okazuje warto艣膰 zmiennej “id” jest nazw膮 pliku, ale o tym nikt nie musi przecie偶 wiedzie膰;
| $fp=fopen($fpath,’r'); |
teraz, aby nasz serwer www, umo偶liwi艂 u偶ytkownikowi pobranie pliku najpierw musi go otworzy膰; za t膮 czynno艣膰 odpowiedzialna jest funkcja “fopen()”, kt贸rej pierwszym parametrem jest nazwa pliku, drugi za艣 tryb otwrcia - w tym przypadku tylko do odczytu;
| $size=filesize($fpath); |
ustalam rozmiar pliku;
| header(”Content-Disposition: attachment; filename=$filename”); header(’Content-Type: application’); header(’Content-Length:’.$size); |
teraz za pomoc膮 funkci “header” wysy艂am do serwera kilka nag艂贸wk贸w http tak, aby ten wiedzia艂 czego od niego chce; pierwsza m贸wi, 偶e chce pobra膰 (”attachment”) plik , kt贸ry przed chwil膮 zosta艂 otworzony, i nazwa膰 go “filename”; druga okre艣la typ zawarto艣ci - dane binarne; trzecia za艣 m贸wie ile bit贸w danych serwer ma wys艂a膰;
| fpassthru($fp); |
teraz przesy艂am dane z pliku na serwerze do przegl膮darki…
| fclose($fp); |
…i na ko艅cu zamykam plik;
Komentarz
Algorytm w takiej postaci nie do ko艅ca jest wygodny. Sprawdza si臋聽doskonale w przypadku skryptu automatycznie wysy艂aj膮cego pliki na serwer a nast臋pnie udost臋pniaj膮cego je do pobrania. W moim przypadku skrypt podczas wysy艂ania na bazie “session_id()” oraz “strtotime()” generuje unikalny ci膮g znak贸w, kt贸ry jest nazw膮 pliku na serwerze, nast臋pnie zar贸wno nazw臋 oryginaln膮 jak i nazw臋 przypisan膮, oraz losowo utworzon膮 pe艂n膮 艣cierzk臋 zapisuje do bazy danych. Nast臋pnym krokiem jest聽napisanie聽skryptu聽generuj膮cego przez odpowiednie zapytanie SQL stron臋 z odno艣nikami.
Wady
Je艣li do przechowywania nazw plik贸w wykorzystywana jest baza danych nale偶y liczy膰 si臋聽z tym, 偶e w momencie jej utraty, lub awari, nie rozgryziesz kt贸ry plik jest kt贸ry.