Upload plików w PHP

No Comments

Na ten temat rozpisywano się wiele razy, jak chociażby w oficjalnym manualu PHP, więc streszczę krótko i po polsku, dla początkujących, gdyż ten temat może mi się przydać w następnych wpisach.

Struktura formularza

Tutaj sprawa jest dosyć prosta. Zwykły formularz powinien tyko posiadać tag enctype oraz pole INPUT typu file. Jak to wygląda w praktyce:

<form action="plik_obslugujacy.php" enctype="multipart/form-data" method="post">
<input name="MAX_FILE_SIZE" type="hidden" value="40000" />
<input name="plik" type="file" />
<input type="submit" value="Prześlij" />
</form>

Po umieszczeniu w formularzu pola typu file, przeglądarka sama postara się o dodanie przycisku “Przeglądaj” oraz procedury obsługi okna “Otwórz plik”.

Ukryte pole "MAX_FILE_SIZE" określa oczywiście maksymalny rozmiar pliku. Jeśli nie zostanie umieszczone w formularzu, zostanie przyjęty domyślny maksymalny rozmiar pliku, zamieszczony w pliku konfiguracyjnym PHP (php.ini).
Rozmiar ten jest określony przez zmienną środowiskową upload_max_filesize. Aby poznać aktualną wartość tej zmiennej (ustaloną zwykle przez administratora), należy użyć funkcji ini_get():

echo ini_get("post_max_size");

Niestety, maksymalnej wielkości uploadowanego pliku nie da się zmienić za pomocą standardowej funkcji ini_set(). Należy się uciec do pliku konfiguracyjnego, czyli .htaccess, umieszczonego w katalogu skryptu.
Przykładowa zawartość takiego pliku to:

php_value post_max_size 10M
php_value upload_max_filesize 10M
php_value max_execution_time 60000

Jak widać, zwiększamy tu nie tylko maksymalną wielkość pliku, ale też maksymalną objętość danych przesyłanych przez POST oraz czas wykonywania skryptu.

Doskonale, skoro już uporaliśmy się z tym problemem, przejdźmy dalej. Z kodu HTML powyżej wynika, że wysyłamy formularz do pliku plik_obslugujacy.php. Zajmujmy się zawartością tego pliku.
Wszystko, co jest zawarte w polach typu file, ląduje w pliku docelowym w tablicy $_FILES. Przykładowa struktura tej tablicy wygląda następująco:

Array
(
    [plik] => Array
        (
            [name] => wordpress.zip
            [type] => application/zip
            [tmp_name] => /tmp/phpB0E.tmp
            [error] => 0
            [size] => 1514600
        )
)

Jak widać, nasz plik został załadowany na serwer i umieszczony w katalogu tymczasowym, z równie tymczasową nazwą.

Kody błędów zwracane w polu error są następujące:
0 – brak błędu
1 – plik większy niż maksymalny rozmiar określony w php.ini (lub .htaccess)
2 – plik większy niż rozmiar określony przez pole MAX_FILE_SIZE formularza
3 – załadowano tylko część pliku
4 – brak pliku (zdarza się, kiedy wyślemy formularz z pustym polem typu file)
6 – brak katalogu tymczasowego
7 – błąd zapisu
8 – upload zatrzymany, błąd rozszerzenia
(nie, nie pomyliłem się, w manualu nie ma nic o kodzie 5)

Oczywiście zalecam stworzenie obsługi pola error, zaś na potrzeby tego artykułu wystarczy zaznaczyć, iż plik został załadowany prawidłowo, jeśli została mu przydzielona tymczasowa nazwa. Taki plik należy tylko skopiować z lokacji tymczasowej do określonego przez nas katalogu i można już na nim działać (lub zostawić w spokoju).

  if($_FILES["plik"]["tmp_name"])
    move_uploaded_file($_FILES["plik"]["tmp_name"],
                       $mojKatalog . "/" . $_FILES["plik"]["name"]);

Oczywiście, jeśli nie zależy nam na kopii pliku, a jedynie jednorazowo na jego zawartości można operować bezpośrednio na pliku tymczasowym.

Myślę, że to wszystko, co trzeba wiedzieć o “zwykłym” uploadzie plików. W planach: asynchroniczny upload plików.

Categories: PHP, Zabawy z kodem Tags: Tagi:, ,

Leave a Reply

Your email address will not be published. Required fields are marked *