Телефон: +7 (926) 245-03-63

Как загрузить (upload) файл PHP?

Следующая статья: Переменные PHP внутри функций

Немного теории. Это нужно, для понимания что и как работает.

  • вы в броузере указываете файл для загрузки на сервер;
  • броузер передает выбранный файл на сервер;
  • PHP-интерпретатор на сервере записывает полученный файл во временную директорию. Причем, имя, под которым записывается файл, может быть абсолютно случайным. Это только под Windows PHP пишет файл с именами подобными <b>PHP2<b>.
  • Нам, в принципе, вовсе не обязательно знать под каким именно именем загруженный файл хранится во временной директории. Почему не надо знать?
  • Потому что, вполне достаточно того, что PHP «знает». И, в любом случае, после завершения работы скрипта, этот файл удаляется.
  • Вы говорите PHP, что загруженный файл надо скопировать из временной директории туда, куда хотите.

На этом, сам процесс «аплоада» можно считать завершенным.

Что вы потом сделаете с этим файлом, вопрос другой.

И еще: все трудности под Win32 связанные с «непонимаем» системой конструкции вида «\PHP2»; (кто сталкивался, поймет) кроются в файле php.ini (php3.ini) Лично у меня, это выглядит так (получено опытным путем):

upload_tmp_dir="f:tmp" - php.ini

С такими настройками, никаких проблем я не замечал. Попробуйте.

Теперь про ограничение размера загружаемого файла. Конечно, и в php.ini есть параметр upload_max_filesize, можно ограничить и размер и тип указанием соответствующих параметров в теге FORM, но, в любом из этих случаев мы получим ошибку, которую не сможем обработать. Что не здорово. Поэтому, удобней ограничивать размер в самом скрипте.

НО: РАЗМЕР файла невозможно узнать до ПОЛНОЙ загрузки файла на сервер. Никаким способом.

Также, при uploade, до ЗАВЕРШЕНИЯ загрузки, файл хранится в памяти, потом пишется во временную директорию, и, еще раз напомню, сразу удаляется из temp по завершению работы скрипта. Вообщем, с помощью PHP не получится сделать индикатор загрузки файлов.

Итак, сначала у нас файл upload.html примерно такого вида.

<html>
<head>
<title>Upload</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
<!-- обратите внимание на enctype!!! -->
<input type="file" name="file1" /><br />
<input type="file" name="file2" /><br />
<input type="submit" name="upload" value="Загрузить" />
</form>
</body>
</html>

Теперь, сам скрипт.

<?php
$max_size=65535;
// максим. размер в БАЙТАХ
$type_1='application/x-zip-compressed';
$type_2='text/plain';
// типы файлов, которые мы хотим принимать
$path='/home/test/frob';
// Путь / каталог, куда сохраняем файлы
if (($file1=='none')&&($file2=='none'))
{ echo 'Не выбрано ни одного файла!'; exit; }
if ($file1_size>$max_size)
{ echo 'Неверный размер! Файл '.$file1_name.' НЕ загружен.'; }
elseif (($file1_type!=$type_1) and ($file1_type!=$type_2))
{ echo 'Неверный тип! Файл '.$file1_name.' ('.$file1_type.') НЕ загружен.'; }
else
{ copy($file1,$path.'/'.$file1_name);
  echo 'Вы загрузили файл '.$file1_name.'. Этот файл сохранен в каталоге '.$path.'<br />';
  echo 'Размер файла - '.$file1_size.' байт<br />';
  echo 'Тип файла - '.$file1_type.'<br /><br /><br /><br />';
}
if ($file2_size>$max_size)
{ echo 'Неверный размер! Файл '.$file2_name.' НЕ загружен.';
}
elseif (($file2_type!=$type_1) and ($file2_type!=$type_2))
{ echo 'Неверный тип! Файл '.$file2_name.' НЕ загружен.';
}
else
{ copy ($file2,$path.'/'.$file2_name);
  echo 'Вы загрузили файл '.$file2_name.'. Этот файл сохранен в каталоге '.$path.'<br/>';
  echo 'Размер файла - '.$file2_size.' байт<br />';
  echo 'Тип файла - '.$file2_type.'<br />';
}
?>

Итак, если Вы не удосужились открыть Manual, рассказываю (хотя, FAQ то он, конечно, FAQ, но чтение manual'ов никто не отменял):

В форме есть поле с type=file и именем file1. При аплоаде, у нас возникают переменные:

  • $file1 - имя файла во временной директории;
  • $file1_name - исходное имя файла;
  • $file1_type - MIME тип файла;
  • $file1_size - размер файла;

Так, осталось рассмотреть случай, когда PHP работает в safe-mode. То есть, если вы сделали все как написано, а вам говорят
Safe-mode restriction is effect… Или, про то, что невозможно выполнить команду copy() - попробуйте copy() заменить на move_uploaded_file().

Но, невозможность выполнить copy() может крыться и просто в том, что у PHP-процесса не хватает прав на запись в указанную вами директорию. В этом случае, вам проще всего спросить у своего администратора, какие права должны быть на директорию, в которую хочется записывать файлы.

Фу-у-у-у…

Последний штрих: на самом деле, если вам следует загрузить несколько файлов, не стоит пользоваться приведенной конструкцией. Лучше, обозвать поля для ввода файлов именем, например, file[], а потом разбирать полученный массив file[] уже.

Возможные глюки

Итак, вы сделали форму для аплоада файлов, вы сделали скрипт, который принимает загруженные файлы, но теперь возникла следующая проблема:

Картинки загружаются, но не показываеются. Бинарные файлы загружаются, но не запускаются (или, не распаковываются, если это архив).

Основная причина данной проблемы - Russian Apache.

Именно он (то есть, web-server) перекодирует все что ни попадя. Соответственно, после такой перекодировки, в файлах оказываются замещенными (перекодированными) некоторые символы. Что избежать подобного есть несколько решений:

1) В директории, где лежит скрипт для Upload'a делаем файл .htaccess в котором пишем:

CharsetDisable On

2) В файл httpd.conf дописать строки:

<Location />
CharsetRecodeMultipartForms Off
</Location>

Обычно, этого вполне достаточно для решения проблемы.

Upload и PHP4

в PHP4 работа с upload`ами стала несколько иной. Теперь вся информация о залитых файлах хранится в массиве $HTTP_POST_FILES для примера:

если у нас в форме было так: <input type="file" name="screenshot"> то информацию о файле надо смотреть здесь:

$HTTP_POST_FILES['screenshot']['name']

Оригинальное имя файла. Например «screen1.jpg»

$HTTP_POST_FILES['screenshot']['type']

mime type файла. Например «image/gif».

$HTTP_POST_FILES['screenshot']['size']

Размер файла в байтах

$HTTP_POST_FILES['screenshot']['tmp_name']

Временное имя файла на сервере.

Интересное в интернете: Уфа сайт пожарные рукава.