загрузка файлов на сервер используя php
При этом в поле action должен быть указан URL Вашего php-скрипта, который в дальнейшем будет заниматься обработкой загружаемых файлов. Скрытое поле MAX_FILE_SIZE должно предшествовать полю выбора файла, и содержать максимально допустимый размер файла в байтах. Его назначение – проверка размера файла еще до момента отправки файла на сервер. Это должно избавить пользователя от длительной и безрезультатной загрузки файла на сервер и образования лишнего трафика, но не стоит особо полагаться на это ограничение, так как его легко обойти.
Что происходит, когда пользователь выбрал файл на своем диске, и нажал на кнопку Send file? Браузер отсылает файл на сервер, где php-интерпретатор помещает его в свою временную директорию, присваивая ему случайное имя и выполняет скрипт, указанный в поле action.
Как должен выглядеть upload.php?
<?php
$uploaddir = '/var/www/uploads/';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir .
$_FILES['userfile']['name'])) {
print "File is valid, and was successfully uploaded.";
} else {
print "There some errors!";
}
?>
При написании скрипта, возникает естественный вопрос: как получить информацию о загруженном файле и достучаться до самого файла. Если Вы используете PHP версии 4.1.0 и старше, лучше всего будет обратиться к глобальному массиву $_FILES. Для каждого загруженного файла он содержит хеш-массив, со следующими данными: $_FILES['userfile']['name'] – оригинальное имя файла, такое, каким его видел пользователь, выбирая файл; $_FILES['userfile']['type'] – mime/type файла, к примеру, может быть image/gif; это поле полезно сохранить, если Вы хотите предоставлять интерфейс для скачивания загруженных файлов; $_FILES['userfile']['size'] – размер загруженного файла; $_FILES['userfile']['tmp_name'] – полный путь к временному файлу на диске; $_FILES['userfile']['error'] – Начиная с версии 4.2.0, содержит код ошибки, который равен 0, если операция прошла успешно.
Для PHP версии ниже 4.1.0 (Рекомендуется немедленно обновить http://www.php.net/downloads.php) этот массив называется $HTTP_POST_FILES. Не стоит забывать, что в отличие от $_FILES этот массив не является суперглобальным и при обращении к нему, к примеру, из функции, необходимо явно указывать global $HTTP_POST_FILES;
Если в настройках Вашего сервера register_globals=on, будут созданы дополнительные переменные вида $userfile_name, $userfile_type, $userfile_size: Учитывая, что, начиная с версии 4.2.0, в настройках по умолчанию register_globals=off использования этих переменных не рекомендовано, даже если они определены. Лучший способ получения информации о загружаемых файлах – использовать массив $_FILES.
Для работы с загруженными файлами лучше всего использовать встроенные функции is_uploaded_file и move_uploaded_file, которые проверяют, был ли загружен файл, и помещают его в указанную папку соответственно. Более детальную информацию Вы можете найти на страницах руководства. Не стоит изобретать велосипед и работать самому с временными файлами, копировать их, удалять. Это уже сделано до Вас и для Вас. Настройка сервера
Я все сделал правильно, но у меня что-то не работает. Может, у меня неправильно сконфигурирован сервер?
Если Вы «все сделали правильно», но Ваш код неработоспособен, или работает неправильно, не спешите отчаиваться. Возможно проблема не в Ваших руках, а в неверных настройках сервера. Вот список директив, которые имеют отношения к загрузке файлов:
В файле php.ini: Если Вы хотите узнать, где расположен Ваш php.ini, выполните
<?php phpinfo(); ?> file_uploads – возможность запретить или разрешить загрузку файлов в целом. По умолчанию On. upload_max_filesize – максимальный размер файла, который может быть загружен. Если Вам необходимо работать с большими файлами, измените эту настройку. По умолчанию 2М. Не забудьте изменить post_max_size. post_max_size – общее ограничение сверху на размер данных, передаваемых в POST запросе. Если Вам необходимо работать с большими файлами, или передавать несколько файлов одновременно, измените эту настройку. Значение по умолчанию 8М. upload_tmp_dir – временная директория на сервере, в которую будут помещаться все загружаемые файлы. Проверьте, какие на нее выставлены права(если на данном этапе у Вас возникли сложности, смотрите пояснения в конце статьи). Такая директория должна существовать и у пользователя, под которым выполняется Apache, также должны быть права на запись в эту директорию. Если Вы работаете с включенным ограничением open_basedir – то временный каталог должен находиться внутри. Вам не нужно заботиться о ее чистке или об уникальности имен, PHP решает эту проблему за Вас.
В файле httpd.conf: Прежде всего, убедитесь, что Вы используете веб-сервер Apache 1.3 (последняя версия на момент написания статьи – 1.3.27). Если Вы используете Apache 2.0, Вам следует прочитать следующий отрывок из документации:
Do not use Apache 2.0 and PHP in a production environment neither on Unix nor on Windows. Если Вы получили сообщение POST Method Not Allowed, это означает, что надо искать что-то похожее на следующие директивы, и использовать ключевое слово Allow:
<Limit POST > Order allow,deny Allow from all </Limit> Проблемы с загрузкой бинарных файлов – классический вопрос «почему бьются файлы при upload». Вот способ решения, предложенный Димой Бородином (http://php.spb.ru): В директории, где лежит скрипт, делаем файл .htaccess, в котором пишем: CharsetDisable On. В файл httpd.conf дописать строки:
<Location /> CharsetRecodeMultipartForms Off </Location>
Небольшие пояснения, к этому рецепту: вышеописанная проблема, когда загруженные на сервер архивы не распаковываются и картинки не отображаются, может возникать из-за того, что используется веб-сервер Russian Apache. Директива CharsetDisable отключает модуль charset-processing module, т.е. никакой перекодировки при скачивании файлов, находящихся в данной папке, происходить не будет. Директива CharsetRecodeMultipartForms выключает перекодировку данных, переданных методом POST с заголовком Content-Type: multipart/form-data. Т.е. двоичные данные, переданные с такой настройкой, будут оставлены в первоначальном виде, а все остальное наполнение сайта будет перекодировано согласно текущим настройкам сервера.
Но при этом могут возникнуть осложнения: будьте готовы к тому, что в некоторых случаях текстовые части запросов вам придется перекодировать самостоятельно. Вот что по этому поводу говорится в документации:
Используйте директиву CharsetRecodeMultipartForms, которая появилась в PL23, но при этом вам все-равно придется перекодировать вручную текстовые части запросов. Для этого можно использовать Russian Apache API, доступное в других модулях или Russian Apache Perl API, доступное из mod_perl.
Один из примеров определения кодировки вы можете найти тут: http://tony2001.phpclub.net/detect_charset/detect.phps
Самая свежая документация по Russian Apache находится на его официальном сайте: http://apache.lexa.ru/.
Не забывайте, что после любой смены конфигурации, Вам необходимо перезапустить Ваш веб-сервер.