Po pierwsze trzeba zaopatrzyć formularz w specjalne pole typu FILE, które umożliwi użytkownikowi wybranie pliku z dysku. Trzeba także do tagu <form>
dodać atrybut enctype="multipart/form-data". W formularzu może także pojawić się pole typu HIDDEN o nazwie MAX_FILE_SIZE i wartości maksymalnej ilości bajtów, które można przesłać, nie jest to jednak skuteczne zabezpieczenie.
Po stronie serwera plik zostaje zapisany do tymczasowego folderu, z którego zostaje usunięty po wykonaniu skryptu. Aby zatrzymać plik na serwerze trzeba go w trakcie działania skryptu przenieść w określone miejsce. Ścieżka do uploadowanego pliku znajduje się w zmiennej:
$HTTP_POST_FILES['nazwa_pola_file']['tmp_name'];
Oprócz tego mamy do dyspozycji:
$HTTP_POST_FILES['nazwa_pola_file']['name'];
- oryginalna nazwa pliku
$HTTP_POST_FILES['nazwa_pola_file']['size'];
- objętość pliku
$HTTP_POST_FILES['nazwa_pola_file']['type'];
- typ MIME, np. 'image/pjpeg', 'application/octet-stream'
Od PHP 4.1.0 można użyć tablicy $_FILES, zamiast tablicy $HTTP_POST_FILES.
Plik można skopiować przy pomocy funkcji copy() jednak, do tego typu operacji zostały zaprojektowane specjalne funkcje takie jak is_uploaded_file() czy move_uploaded_file(), które eliminują możliwości oszukania skryptu.
A teraz jakiś przykład:
<?php
$upload_dir = '.';
$maxfilesize = 102400;
$send = $HTTP_POST_VARS['send'];
$userfile = $HTTP_POST_FILES['userfile'];
$phpself = $HTTP_SERVER_VARS['PHP_SELF'];
if(isset($send)) {
if(is_uploaded_file($userfile['tmp_name'])) {
if($userfile['size'] <= $maxfilesize) {
if(move_uploaded_file($userfile['tmp_name'],
$upload_dir.'/'.$userfile['name']))
echo '<p>Plik został wysłany</p>';
}
}
}
?>
<form action="<?php echo $phpself; ?>" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $maxfilesize; ?>">
<input type="file" name="userfile">
<input type="submit" name="send" value="Wyślij plik">
</form>
To by było na tyle...
Gites majonez :))
szymek znalazl "dziure", w kodzie brak filtra, ktory nie pozwoli na upload skryptow php,php3...
Jednym z trudnych do wykrycia błędów jest ustalanie MAX_FILE_SIZE jako stałej. Tymczasem jest ona ustalana w php.ini. Oto przykład jak się do niej dostać:
/**
Zwraca liczbę skonwertowaną z postaci czytelnej na postać liczbową.
*/
function return_bytes( $val )
{
$val = trim( $val );
$last = $val{strlen( $val )-1};
$last = strtolower( $last );
switch( $last )
{
case \'k\':
return (int) $val 1024;
break;
case \'m\':
return (int) $val 1024 * 1024;
break;
default:
return (int) $val;
}
}
/**
*/
function getUploadMaxFileSize()
{
return return_bytes( ini_get( \'upload_max_filesize\' ) );
}
I jeszcze jdeno: ścieżka docelowa musi być pełną ścieżką na serwerze. Więc przykład powienien wyglądać tak:
$upload_dir = $_SERVER[\'DOCUMENT_ROOT\'];
Od czasu kiedy mamy php 4.1 wszystkie przeslane do serwera pliki sa dostepne w superglobalnej tablicy $_FILES. Kazdy plik ma po przeslaniu 4 zmienne:
name: nazwa elementu formularza skojarzonego z danym plikiem
type: Typ MIME pliku
size: rozmiar tego pliku w bajtach
tmp_name: maiejsce tymczasowego skladania pliku na serwerze.
A teraz przyklad:
//Kod HTML przesylajacy plik:
< input type="file" name="uploady" >
//Aby zapisac plik:
move_uploaded_file($_FILES['uploady'][tmp_name], 'sciezka/do/katalogu_w_ktorym_plik/zostanie_zapisany")
warto pamietac ze tmp_name daje pelna sciezke dostepu to pliku. Nazwe wlasciwa wyodrebnia funkcja basename()