PHP FAQ

Jak uploadować plik na serwer przy pomocy formularza

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 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...

FAQ

5 komentarzy

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()

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\' ) );
    }

szymek znalazl "dziure", w kodzie brak filtra, ktory nie pozwoli na upload skryptow php,php3...

Gites majonez :))