Forum und email
Zpracování uploadu souborů

Kapitola 38. Zpracování uploadu souborů

Uploading metodou POST

PHP umožňuje zpracování uploadu souborů z jakéhokoli prohlížeče vyhovujícího RFC-1867 (což zahrnuje mj. Netscape Navigator 3 a pozdější, Microsoft Internet Explorer 3 se záplatou od Microsoftu, nebo pozdější bez záplaty). Tato schopnost umožňuje lidem uploadovat textové i binární soubory. S autentizací poskytovanou PHP a s funkcemi pro manipulaci se soubory máte plnou kontrolu nad tím, kdo smí uploadovat a co se má udělat s uploadovaným souborem.

Nezapomeňte, že PHP podporuje také uploady metodou PUT tak, jak se používá v Netscape Composeru a v editoru Amaya od W3C. Pro bližší detaily viz Podpora metody PUT.

Obrazovka pro upload souboru může být tvořena speciálním formulářem, který vypadá podobně jako tento:

Příklad 38-1. Formulář pro upload souboru

<form enctype="multipart/form-data" action="_URL_" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="1000">
Send this file: <input name="userfile" type="file">
<input type="submit" value="Send File">
</form>
_URL_ by mělo označovat PHP soubor. Skryté pole MAX_FILE_SIZE musí předcházet pole pro vložení souboru a jeho hodnota specifikuje maximální akceptovanou velikost souboru. Hodnota je v bytech.

Varování

Hodnota MAX_FILE_SIZE je z hlediska prohlížeče pouze informativní. Je snadné ji obejít. Takže nepočítejte s tím, že prohlížeč se bude chovat tak, jak si přejete. Nastavení maximální velikosti v PHP však samozřejmě nemůže být obelstěno.

Proměnné definované pro uploadované soubory se liší v závislosti na verzi a konfiguraci PHP. Pokud je aktivní volba track_vars, bude inicializováno pole $HTTP_POST_FILES/$_FILES. Konečně, související proměnné mohou být inicializovány jako globální, pokud je zapnuta volba register_globals. Ovšem používání globálních proměnných není doporučeno. Po úspěšném uploadu budou v cílovém skriptu definovány následující proměnné:

Poznámka: track_vars je od PHP 4.0.3 vždy zapnuto. U PHP 4.1.0 a pozdějších může být použito $_FILES namísto $HTTP_POST_FILES. $_FILES je vždy globální proměnná, takže by se neměla používat specifikace global pro proměnnou $_FILES.

$HTTP_POST_FILES/$_FILES obsahuje informace o uploadovaném souboru.

Obsah $HTTP_POST_FILES je takovýto (uvědomte si, že se předpokládá použití názvu uploadovaného souboru 'userfile' tak, jako v příkladu výše):

$HTTP_POST_FILES['userfile']['name']

Originální název souboru na klientském počítači.

$HTTP_POST_FILES['userfile']['type']

MIME typ souboru, pokud prohlížeč tuto informaci poskytuje (např. "image/gif").

$HTTP_POST_FILES['userfile']['size']

Velikost uploadovaného souboru v bytech.

$HTTP_POST_FILES['userfile']['tmp_name']

Dočasný název souboru, pod nímž byl uploadovaný soubor uložen na server.

Poznámka: PHP 4.1.0 a pozdější podporují zkrácený název proměnné $_FILES. PHP 3 nepodporuje $HTTP_POST_FILES.

Obsah proměnnách v situaci, kdy je proměnná register_globals zapnuta nastavením v souboru php.ini (uvědomte si, že se předpokládá použití názvu uploadovaného souboru 'userfile' tak, jako v příkladu výše):

  • $userfile - Dočasný název souboru, pod kterým byl uploadovaný soubor uložen na server.

  • $userfile_name - Originální název souboru nebo cesta na odesílajícím systému.

  • $userfile_size - Velikost uploadovaného souboru v bytech.

  • $userfile_type - MIME typ souboru, pokud prohlížeč tuto informaci poskytuje (např. "image/gif").

Uvědomte si, že proměnná "$userfile" ve skutečnosti představuje název pole <input> se specifikací type="file" ve formuláři. Pro výše uvedený příklad jsme zvolili název "userfile".

Poznámka: Nastavení register_globals = On se nedoporučuje z bezpečnostních a výkonnostních důvodů.

Soubory se implicitně ukládají do systémového adresáře pro dočasné soubory, pokud nebylo direktivou upload_tmp_dir v souboru php.ini stanoveno jinak. Systémový adresář pro dočasné soubory může být změněn nastavení proměnné prostředí TMPDIR v prostředí, kde PHP běží. Nastavení za použití putenv() z PHP skriptu nebude fungovat. Tato proměnná prostředí může být také použita k ujištění se, že všechny ostatní operace pracují s uploadovanými soubory.

Příklad 38-2. Ověřování uploadu souboru

Následující příklady jsou pro verze PHP 4 vyšší než PHP 4.0.2. (viz funkce is_uploaded_file() a move_uploaded_file()).

<?php
// V PHP 4.1.0 a pozdějších by mělo být použito $_FILES namísto $HTTP_POST_FILES.
if (is_uploaded_file($HTTP_POST_FILES['userfile']['tmp_name'])) {
    
copy($HTTP_POST_FILES['userfile']['tmp_name'], "/place/to/put/uploaded/file");
} else {
    echo
"Possible file upload attack. Filename: " . $HTTP_POST_FILES['userfile']['name'];
}
/* ...or... */
move_uploaded_file($HTTP_POST_FILES['userfile']['tmp_name'], "/place/to/put/uploaded/file");
?>

PHP skript, který přijímá uploadované soubory, by měl implementovat veškerou logiku pro stanovení, co by se mělo udělat s uploadovaným souborem. Můžete např. použít proměnnou $HTTP_POST_FILES['userfile']['size'] pro zahození souborů, které jsou příliš malé nebo velké. Mohli byste použít také proměnnou $HTTP_POST_FILES['userfile']['type'] pro filtraci souborů podle MIME datového typu. Bez ohledu na řešení, soubor by měl být smazán nebo přesunut jinam.

Soubor bude automaticky smazán z dočasného adresáře na konci skriptu, pokud nebyl přesunut jinam nebo přejmenován.