|
|
|
|
File Uploads |
|
|
20.11.2003 16:24 |
2 |
|
|
|
|
|
printer friendly version |
Upload fileova putem POST metode.
Ovaj tutorial objašnjava kako uploadati fileove
putem POST metode na vaš web prostor.
Kao što PHP manual kaže, php je sposoban uploadati fajle putem browsera.
Ako namjeravate koristiti file upload na web serveru kojeg imate
instalirano offline (phpdev, "ručno" podešen web server)
onda trebate pogledati ove postavke u php.ini fileu:
- file_uploads (on ili off, očito mora
biti ON da bi radilo :>)
- upload_tmp_dir (ako nije navedeno,
koristi defaultni sistemski temporary direktorij)
- upload_max_filesize (najveći mogući
size filea kojeg šaljemo)
- post_max_size (najveći size kojeg
možemo slati via post method)
Dakle, u php.ini fileu morate imati file_uploads
= On, upload_tmp_dir ne mora
biti naveden, upload_max_filesize = 16M
(tako ja imam), te post_max_size = 16M.
Ako php imate instaliran kao modul, ne zaboravite restartati web server nakon što promijenite neku od vrijednosti u php.ini fileu.
|
|
HTML formular za upload našeg filea: |
<form enctype="multipart/form-data"
action="uploadaj.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE"
value="61440">
Uploadaj: <input name="file_name"
type="file"> <input
type="submit" value="Uploadaj">
</form> |
|
|
Kao što vidite, enctype formulara je
multipart/form-data za razliku od standardnog enctypea. Formular
MORA biti multipart/form-data kako bi upload radio. Ako stavite drugi
enctype, nećete poslati file na server nego samo ime filea :)
Action, kao što i znate predstavlja skriptu
koja ce obraditi podatke koje šaljemo.
Slijedi jedan hidden field kojeg smo nazvali MAX_FILE_SIZE.
Čemu on služi? MAX_FILE_SIZE služi kako
bi direktno u formularu odredili maksimalnu veličinu filea (u byteovima,
u ovom slučaju iznosi 60KB). Primjerice, vaš upload_max_filesize
je 2 megabajta, a netko želi poslati file od 3 megabajta na vaš server.
Osoba će morati čekati dok se file ne uploada na server kako bi joj server
potom javio grešku. Drugi slučaj može biti da je vaš upload_max_filesize
50 megabajta, ali vi želite da svatko uploada maximalno 200 kb. Zato postoji
MAX_FILE_SIZE koji će upozoriti čovjeka
da pokušava poslati prevelik file. Ako se MAX_FILE_SIZE
premaši, php će upozoriti korisnika da je pokušao poslati prevelik file,
file se NEĆE poslati ali skripta se neće prestati izvršavati i to je bitno
imati na umu!
Doduše, ova "fora" neće raditi uvjek, odnosno nije 100% sigurna.
Zašto? Pa većina browsera se može konfigurirati da ne šalje određeni podatak
ili ne šalju podatke koje najpopularniji browseri šalju, pa tako netko
tko spada u onu grupu korisnika koji koriste stare browsere ili browsere
sa nedovoljno featurea može "preskočiti" ovu provjeru.
U našu skriptu ćemo dodati i provjeru veličine poslanog filea. |
|
Preddefinirane varijable PHP-a: $_FILES. |
Što je to? $_FILES
je varijabla u koju se sprema podatak o fileu kojeg šaljemo via POST
metode. Naš file field smo nazvali file_name
te kada kliknemo na "Uploadaj" gumb, php će dodjeliti varijabli
$_FILES informacije o fileu kojeg šaljemo.
Krenimo sa kodom skripte "uploadaj.php"
te ću tamo objasniti varijablu $_FILES. |
|
|
uploadaj.php |
<?php
$temp_filename = $_FILES['file_name']['tmp_name'];
$ime_filea_na_disku = $_FILES['file_name']['name'];
$size_u_bajtovima = $_FILES['file_name']['size'];
Objašnjenje:
$_FILES je jedna podatkovna struktura koja se naziva polje
ili array. Polja imaju pokraj svog imena indekse
u uglatim zagradama.
O poljima će bit više govora u budućim tutorialima. Ovdje je bitno
zapamtiti da ne treba postavljati više od 3 indeksa u bilo kojem
polju jer inače veličina polja naraste ohoho i vi padnete programiranje
:)
Prvi indeks polja (arraya) $_FILES se "zove"
file_name. Ako pogledate naš HTML formular
za upload, vidjeti ćete da se i file field zove file_name.
Osnovnom logikom dolazite do jednostavnog zaključka - ime file fielda
mora biti jednako prvom indeksu $_FILES
varijable.
Pogledajmo $temp_filename
= $_FILES['file_name']['tmp_name'];
Ja sam nazvao varijablu $temp_filename
i pridružio joj vrijednost $_FILES['file_name']['tmp_name'];
Indeks ['tmp_name'] sadrži
ime filea na serveru nakon uploada. Kada pošaljete file na server,
server će ga utrpati u tmp_dir naveden u php.ini datoteci pod nekim
random/čudnim imenom te ovaj indeks sadrži to ime.
$ime_filea_na_disku = $_FILES['file_name']['name']
sadrži "originalno" ime datoteke kakvo je bilo na korisnikovom
disku, dok indeks ['size'] sadrži veličinu u bajtovima.
Idemo nazad na kod:
<?php
$temp_filename = $_FILES['file_name']['tmp_name'];
$ime_filea_na_disku = $_FILES['file_name']['name'];
$size_u_bajtovima = $_FILES['file_name']['size'];
// ako je korisnik nekako
prešao preko MAX_FILE_SIZE provjere u formularu
$zeljena_max_velicina = 1024*60; // 60 KB
if($size_u_bajtovima > $zeljena_max_velicina
+ 1) {
die('Poslali ste prevelik file');
}
$direktorij = 'uplodani_fajlovi/'.
$ime_filea_na_disku .'';
if(move_uploaded_file($temp_filename,
$direktorij)) {
echo 'File je uploadan <a
href = "index.html">Vrati se na index</a>';
} else {
echo 'Niste naveli file za upload';
die();
}
?>
Varijabla $direktorij
sadrži nekakav direktorij "kroz" originalno ime filea.
Vi ćete "kopirati" izvorni file u neki direktorij u određeno
"ime". To je sistem preko kojeg se to radi i to treba
zapamtiti i koristiti. Napomena: ako se u direktoriju u kojem se
nalazi skripta za upload NE nalazi direktorij imena "uplodani_fajlovi",
php će vam prijaviti grešku.
move_uploaded_file() je funkcija
koja prima 2 argumenta - source i destination, iliti ulazni file
te krajnji direktorij gdje trpamo taj file. Funkcija vraća TRUE
ako je file kojeg šaljemo bio valjan i ako je uspješno "premješten".
Ako filea nije bilo, move_uploaded_file()
vraca vrijednost FALSE te se ništa ne događa
(osim što mi prijavimo grešku fk0rz).
Ako je file uploadan, ali dođe do nekakve greške prilikom njegovog
micanja, funkcija nece ništa poduzeti, vratiti će vrijednost FALSE
te ovisno o situaciji će prijaviti grešku.
Ako uploadate file, ali file sa istim imenom postoji u direktoriju
određenom za upload, funkcija move_uploaded_file()
će ga overwritati. |
|
|
Single quotes (') vs. Double quotes (") |
Možda ste primjetili da indekse stalno navodimo u jednostrukim navodnicima ($_FILES['file_name']['type']. Zar nismo mogli pisati dvostruke navodnike. Mogli smo, ali postoji razlika. Kada se string nalazi unutar dvostrukih navodnika, PHP parsa taj string tražeći varijable unutar njega i ako ih nađe zamjenjuje ih vrijednošću varijable. Ako je string unutar jednostrukih navodnika, ne radi se nikakvo parsanje što je marginalno brže. To ubrzanje možda nećete osjetiti, pogotovo ako u vašem programu nema puno takvih deklaracija ali svejedno, radi se o good coding practice.
Npr.
$name = 'test';
echo $moj_array["indeks_$name"]; // ispisuje vrijednost polja $moj_array['indeks_test']
echo $moj_array['indeks_$name']; // ispisuje vrijednost polja $moj_array['indeks_$name'], vjerojatno ne ono što želimo
|
|
|
Tip filea kojeg uploadamo |
Osim navedenih indeksa preddefinirane varijable
$_FILES, postoji još $_FILES['file_name']['type']
index koji sadrži mime-type filea (ako je browser pružio tu informaciju).
Ako želite uploadati isključivo jedan tip filea, npr. samo GIF slike,
možete upotrijebiti slijedeći sistem:
<?php
// preskačem prvi dio koda
$tip_filea = $_FILES['file_name']['type'];
if($tip_filea
!= 'image/gif')
{
die('Probali
ste poslati file koji nije GIF!');
}
//
?>
Navesti ću neke typeove koje browser prijavljuje: image/gif, image/jpeg,
image/png, application/x-shockwave-flash, image/psd, image/bmp,
image/tiff, image/tiff, application/octet-stream, image/jp2, application/x-shockwave-flash,
image/iff, image/vnd.wap.wbmp, image/xbm. Za više typeova preporučam
konzultaciju sa www.php.net
i googleom. |
|
|
Error kodovi (php 4.2.0 i veći) |
Još jedan indeks varijable
$_FILES - ['error'].
Neću ulaziti u primjenu svih error kodova u kodu skripte koju smo
koristili za potrebe ovog tutoriala, već ću navesti error kodove te
njihovo objašnjenje (istu stvar možete pronaći u php manualu, ali
kad vec objašnjavamo upload fileova, onda je potrebno spomenuti i
ovaj segment). $_FILES['file_name']['error']
može poprimiti slijedece vrijednosti:
UPLOAD_ERR_OK
Vrijednost: 0; Nema greške, upload je prošao dobro.
UPLOAD_ERR_INI_SIZE
Vrijednost: 1; File je veci od upload_max_filesize direktive navedene
u php.ini fileu.
UPLOAD_ERR_FORM_SIZE
Vrijednost: 2; Uploadani file premašuje MAX_FILE_SIZE direktivu
koja je bila navedena u html formularu.
UPLOAD_ERR_PARTIAL
Vrijednost: 3; File je samo djelomicno uploadan.
UPLOAD_ERR_NO_FILE
Vrijednost: 4; Ništa nije uploadano.
Izgled skripte uz upotrebu error kodova:
<?php
$temp_filename = $_FILES['file_name']['tmp_name'];
$ime_filea_na_disku = $_FILES['file_name']['name'];
$size_u_bajtovima = $_FILES['file_name']['size'];
if($_FILES['file_name']['error']
== 2) die(); // prekid izvršavanja u slučaju da error kod iznosi
2
// ako je korisnik nekako
prešao preko MAX_FILE_SIZE provjere u formularu
$zeljena_max_velicina = 1024*60; // 60 KB
if($size_u_bajtovima > $zeljena_max_velicina
+ 1) {
die('Poslali ste prevelik file');
}
$direktorij = 'uplodani_fajlovi/'.
$ime_filea_na_disku .'';
if(move_uploaded_file($temp_filename,
$direktorij)) {
echo 'File je uploadan <a
href = 'index.html'>Vrati se index</a>';
} else {
echo 'Niste naveli file za upload';
die();
}
?>
|
|
|
Upload više fileova odjednom |
Recimo da želite uploadati 2 file odjednom. Možete
to napraviti tako da ubacite 2 file fielda u formular i svakom date
različito ime te da u skripti imate "dupli" kod za provjeru
svakog od filea. Recimo da jednog dana i mi dobijemo ADSL-ove od par
megabita te vi želite uploadati 600 fileova odjednom. Pisati 600 puta
istu stvar? Ako je odgovor ne, pročitajte slijedeće: <form
enctype="multipart/form-data" action="uploadaj.php"
method="POST">
<input type="hidden" name="MAX_FILE_SIZE"
value="64000">
Uploadaj prvi: <input name="file_name[]" type="file">
Uploadaj drugi: <input name="file_name[]" type="file">
Uploadaj treći: <input name="file_name[]" type="file">
<input type="submit" value="Uploadaj">
</form>
Stisnemo na Uploadaj i što se dogodi? Varijabla $_FILES
dobije i treći indeks te sveukupno to izgleda ovako:
$_FILES['file_name']['tmp_name'][0];
// ovisno o tome koliko je filea uploadano, toliko indeksa će $_FILES
poprimiti počevši, naravno, sa brojkom 0 a ne 1 (napomena za one
koji ne znaju ništa o poljima)
Zašto necu staviti opis uploadanja više fileova? Jer povlači za
sobom objašnjavanje petlji, prefiksnih i postfiksnih operatora,
polja i sl. te ću ovaj dio ostaviti za neki slijedeći tutorial. |
|
|
Dodatne informacije |
http://www.php.net/manual/en/features.file-upload.php
|
|
Zaključak |
Gore navedeni primjeri su samo smjernice za napraviti
skriptu koja uploada file sa korisničkog računala. Ljudi koji se tek upoznaju
sa PHP-om moraju imati na uvid da skripta koju smo koristili za potrebe
tutoriala nema restrikciju na pristup, spremanje informacija o fileu kojeg
šaljemo te druge brojne stvari koje bi jedna solidna upload skripta trebala
imati. Ovo je strogo početnički tutorial koji pokazuje kontrolu objekata
formulara poput file fielda te kontrolu nekih varijabli. Ukoliko nešto nije
jasno u svezi tutoriala, molim vas da upotrijebite forum kako bi porazgovarali
o eventualnim nedostacima/previdima. Uživajte u uplodanju :) |
|
Autor: maxy |
|
|
|
|
Komentari
Dobar tutorial mozda bi ga se moglo nadopuniti s mysql bazom. Tj. Mala baza podataka s uploadom :) Kao upload, download skripta. |
|
to već ugo tražim up&down skriptu, ima neko neki link ?? |
Komentar: EX 10.08.2007 03:52 |
|
** Trenutno niste ulogirani pa ne možete ni dodavati komentare ** |
|
|
|