Jak uploadować plik na serwer przy pomocy formularza HTML?
piechnat
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 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 zabezpieczenie, tylko informacja dla klienta.
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 możemy odczytać z
$HTTP_POST_FILES['nazwa_pola_file']['tmp_name'];
Oprócz tego mamy do dyspozycji:
- Oryginalna nazwa pliku:
$HTTP_POST_FILES['nazwa_pola_file']['name'];
- Rozmiar pliku:
$HTTP_POST_FILES['nazwa_pola_file']['size'];
- typ MIME (np.
image/pjpeg
,application/octet-stream
):$HTTP_POST_FILES['nazwa_pola_file']['type'];
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.
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>
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'];
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' ) );
}
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()
szymek znalazl "dziure", w kodzie brak filtra, ktory nie pozwoli na upload skryptow php,php3...
Gites majonez :))