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>

5 komentarzy

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;
    }
    }

/**

  • Zwraca maksymalną wielkość pliku uploadowanego.
    */
    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 :))