php скрипт загрузки файлов на сервер php
Пошаговая инструкция по реализации загрузки файлов на сервер без перезагрузки страницы на PHP + Javascript
Проблема
Недавно я столкнулся с вполне, на мой взгляд, распространённой задачей: нужно обеспечить пользователю возможность загрузить на сервер любое число, скажем, картинок с комментарием к каждой из них в рамках одного интерфейса. В моём случае это было: фото товара, его описание и количество. Для наглядности прикладываю скриншот интерфейса:
Идея и алгоритм решения
Так как описания и фотографии для получения конечного результата можно изменять очень много раз, решено было осуществить следующую схему работы: фотографии загружаются на сервер на одной при клике на фото-иконку, при этом в случае успеха сервер возвращает имя картинки, а при неуспехе — «error». Соответственно, в случае успеха, фото-иконка заменяется на миниатюру загруженного фото, а в скрытое поле формы соответствующей строки сохраняется её имя, а при неуспехе мы получаем фото-иконку и пустое скрытое поле формы соответствующей строки, отвечающее за имя фото. Текстовая же информация при изменении любого поля формы отправляется на сервер вся в формате массив [имяФото, описаниеДетали, количествоШт] — это наиболее универсально: один и тот же метод отвечает за полное обновление списка товаров при их редактировании или удалении. Как известно, AJAX не умеет отправлять файлы, поэтому реализуем процедуру загрузки с помощью обычной формы, в качестве target которой укажем скрытый фрейм, который и будет перезагружаться вместо страницы.
Практическая реализация
Итак, в нашем распоряжении HTML, PHP и Javascript. Поехали:
1. Верстаем на странице форму для загрузки фото. Она содержит только один input, который мы спрячем с помощью css:
2. Создадим на странице скрытый iframe, который и будет перезагружаться в результате отправки формы с файлом:
3. Верстаем таблицу товаров, с которой и будет работать пользователь:
3. Пишем PHP-код загрузки файла:
Мой проект на CodeIgniter, поэтому код вот такой, но в целом, суть в следующем: мы просто загружаем и переименовываем полученный из формы файл, если всё проходит успешно, выводим в наш iframe его имя, если нет — «error».
4. Пишем Javascript, который будет контролировать весь процесс:
Вот, собственно, и весь процесс.
Если возникнет такая необходимость, сделаю демо процесса отдельным блоком и прикреплю сюда ссылку, а так же дам исходники.
PHP class для скачки и закачки файлов на сервер
Предисловие
В интернете есть много информации о том как скачивать файлы с сервера и загружать файлы на сервер, а также между серверами. Но нигде нет простого решения которое было бы более ли менее универсально.
И лишь благодаря единичным статьям, кусочкам информации с форумов и всяким комментариям удалось собрать пазл воедино. Я не утверждаю что мое решение полностью универсально, но очень удобное во многих случаях, хотя это вам решать.
Если у кого-либо возникнет желание улучшить мое решение этого вопроса и хватает знаний в этом направлении, то я буду рад, если вы сделаете какие-либо исправления или добавления к коду который лежит в открытом доступе на GitHub.
А теперь к делу, функции класса CargaDes:
Для начала нужно скачать и подключить класс CargaDes:
1. Отдача файла через браузер без показа его места хранения с возможностью докачки и регулирования скорости
Этот метод очень похож на Drupal и иже с ним:
Я добавил еще отдачу с помощью Apache, но должна быть включена директива XSendFile On
Сразу после выполнения метода браузер выдаст окно для сохранения файла
2. Загрузка файла/ов на сервер через браузер с индикатором прогресса
После выполнения метода появится кнопка для выбора файлов и кнопка для загрузки файлов. Индикатор будет появляться для каждого выбранного файла в отдельности.
3. Скачивание файлов с удаленного сервера на свой сервер
4. Отдаем файл на удаленный сервер со своего сервера
По итогу хочу сказать
Если этот класс поможет хотя бы одному человеку я буду очень рад этому. Как я уже говорил в начале буду рад конструктивной критике и дополнениям которые могут привести к улучшению класса. Ссылка на CargaDes.class.
Изменил в статье способы использования класса. И добавил описание того что изменилось в классе.
Вот закончил работу над ошибками, если это можно так назвать.
Что было не сделано:
В целом я постарался исправить, то о чем говорили в комментариях, если будут найдены еще какие либо недочеты или ошибки — пишите постараюсь исправить.
Благодарю за конструктивную критику webdevium и alutskevich, если бы мог, то плюсанул бы вам обязательно.
Так же благодарю всех остальных т.к. у меня появилось понимание моей главной ошибки и родилось пару идей.
Php скрипт загрузки файлов на сервер php
Multipart-формы
Загрузка фаилов на сервер осуществляется пользователями сети интернет довольно часто, а именно:
Вот так примерно будет выглядеть приведенная multipart-форма (вы можете попробовать с ее помощью посмотреть результат работы multipart-форм, загрузив какой-нибудь файл небольшого размера на сервер):
Multipart-формы обычно используют метод передачи POST. Как видно из предыдущего примера, данная форма имеет два поля:
Обработка multipart-форм
Прежде, чем приступить к написанию скрипта обработки multipart-формы, нужно отредактировать файл конфигурации php.ini, чтобы разрешить загрузку файлов на сервер.
Конфигурационный файл PHP php.ini имеет три параметра, связанные с загрузкой файлов на сервер:
Если ваш веб-сервер работает под управлением операционной системы Linux, то нужно перезапустить сервис:
service httpd restart
После завершения работы скрипта, временный файл будет удален. Это означает, что мы должны его скопировать в другое место до завершения работы скрипта. То есть алгоритм работы сценария загрузки файла на сервер такой:
Копирование файла производится функцией copy():
// На всякий случай создадим каталог. Если он уже создан,
// сообщение об ошибки мы не увидим, поскольку воспользуемся оператором @:
// Копируем файл из /tmp в uploads
// Имя файла будет таким же, как и до отправки на сервер:
// Создаем каталог uploads
chown apache:apache uploads
// Разрешение записи всем (777) + установка закрепляющего бита (1):
chmod 1777 uploads
Вот теперь можно загружать файлы на сервер.
Пишем PHP скрипт загрузки файлов на сервер
Файл успешно загружен на сервер
Ошибка! Не удалось загрузить файл на сервер!
Информация о загруженном на сервер файле:
Загрузка на сервер нескольких файлов
Также предусмотрена возможность автоматического получения организованной в массив информации о нескольких одновременно загружаемых файлах. Для реализации такой возможности используйте тот же синтаксис отправки массива из HTML-формы, что и для множественных полей select и checkbox :
Загрузка файлов на сервер
Содержание
User Contributed Notes 32 notes
Example:
( ‘Content-Type: text/plain; charset=utf-8’ );
echo ‘File is uploaded successfully.’ ;
Clarification on the MAX_FILE_SIZE hidden form field:
PHP has the somewhat strange feature of checking multiple «maximum file sizes».
The two widely known limits are the php.ini settings «post_max_size» and «upload_max_size», which in combination impose a hard limit on the maximum amount of data that can be received.
Please note that using this PHP feature is not a good idea. A form field can easily be changed by the client. If you have to check the size of a file, do it conventionally within your script, using a script-defined integer, not an arbitrary number you got from the HTTP client (which always must be mistrusted from a security standpoint).
Be reminded that this mime type can easily be faked as PHP doesn’t go very far in verifying whether it really is what the end user reported!
My best bet would be for you to check the extension of the file and using exif_imagetype() to check for valid images. Many people have suggested the use of getimagesize() which returns an array if the file is indeed an image and false otherwise, but exif_imagetype() is much faster. (the manual says it so)
IE on the Mac is a bit troublesome. If you are uploading a file with an unknown file suffix, IE uploads the file with a mime type of «application/x-macbinary». The resulting file includes the resource fork wrapped around the file. Not terribly useful.
(There is probably a better way to do it, but this solved my problem):
If «large files» (ie: 50 or 100 MB) fail, check this:
It may happen that your outgoing connection to the server is slow, and it may timeout not the «execution time» but the «input time», which for example in our system defaulted to 60s. In our case a large upload could take 1 or 2 hours.
Additionally we had «session settings» that should be preserved after upload.
1) You might want review those ini entries:
* session.gc_maxlifetime
* max_input_time
* max_execution_time
* upload_max_filesize
* post_max_size
2) Still fails? Caution, not all are changeable from the script itself. ini_set() might fail to override.
You can see that the «upload_max_filesize», among others, is PHP_INI_PERDIR and not PHP_INI_ALL. This invalidates to use ini_set():
http://www.php.net/manual/en/configuration.changes.modes.php
3) Still fails?. Just make sure you enabled «.htaccess» to overwrite your php settings. This is made in the apache file. You need at least AllowOverride Options.
You will necessarily allow this manually in the case your master files come with AllowOverride None.
Depending on the system, to allow «large file uploads» you must go up and up and up and touch your config necessarily up to the apache config.
These work for me, for 100MB uploads, lasting 2 hours:
In the example,
— As I last 1 to 2 hours, I allow 3 hours (3600×3)
— As I need 100MB, I allow air above for the file (110M) and a bit more for the whole post (120M).
For those of you trying to make the upload work with IIS on windows XP/2000/XP Media and alike here is a quick todo.
2) In windows explorer browse to the upload directory created above and share it. To do that execute the following substeps.
a) Right click the folder click «sharing and security. »
b) Check ‘Share this folder on the network’
c) Check ‘Allow network users to change my files’ ( THIS STEP IS VERY IMPORTANT )
d) click ‘ok’ or ‘apply’
3) you can then go in the IIS to set read and write permissions for it. To do that execute the followin substeps.
a) Open IIS (Start/Controp Panel (classic View)/ Admistrative tools/Internet Information Service
b) Browse to your folder (the one we created above)
c) right click and select properties.
d) in the Directory tab, make sure, READ, WRITE, AND DIRECTORY BROWSING are checked.
e) For the security freaks out there, You should also make sure that ‘execute permissions:’ are set to Script only or lower (DO NOT SET IT TO ‘script and executable)'( that is because someone could upload a script to your directory and run it. And, boy, you do not want that to happen).
Send me feed back it if worked for you or not so that I can update the todo.
PS: BIG thanks to oportocala
Using /var/www/uploads in the example code is just criminal, imnsho.
One should *NOT* upload untrusted files into your web tree, on any server.
Nor should any directory within your web tree have permissions sufficient for an upload to succeed, on a shared server. Any other user on that shared server could write a PHP script to dump anything they want in there!
One’s code should INSPECT the actual file to see if it looks kosher.
For example, images can quickly and easily be run through imagegetsize and you at least know the first N bytes LOOK like an image. That doesn’t guarantee it’s a valid image, but it makes it much less likely to be a workable security breaching file.
For Un*x based servers, one could use exec and ‘file’ command to see if the Operating System thinks the internal contents seem consistent with the data type you expect.
I’ve had trouble in the past with reading the ‘/tmp’ file in a file upload. It would be nice if PHP let me read that file BEFORE I tried to move_uploaded_file on it, but PHP won’t, presumably under the assumption that I’d be doing something dangerous to read an untrusted file. Fine. One should move the uploaded file to some staging directory. Then you check out its contents as thoroughly as you can. THEN, if it seems kosher, move it into a directory outside your web tree. Any access to that file should be through a PHP script which reads the file. Putting it into your web tree, even with all the checks you can think of, is just too dangerous, imnsho.
There are more than a few User Contributed notes here with naive (bad) advice. Be wary.
PHP | Загрузка файлов на сервер
В этом уроке рассмотрим основы загрузки файлов в PHP. Во-первых, ознакомимся с параметрами конфигурации PHP, которые должны быть установлены для успешной загрузки файлов на сервер. После этого разберём реальный пример загрузки файла.
Настройка параметров PHP
Существует множество различных настроек конфигурации PHP, которые нам следует сначала проверить для успешной загрузки файлов. В этом уроке мы рассмотрим некоторые параметры, которые важны для загрузки файлов PHP. Эти параметры можно настроить в файле php.ini.
Где находится php.ini?
Местонахождение файла php.ini зависит от операционной системы, на которой работает сервер вашего хостинг-провайдера. Чтобы узнать где находится php.ini выполним следующие шаги:
Приведём фрагмент из установочного файла с некоторыми полезными значениями по умолчанию:
Директория upload_tmp_dir устанавливает временный каталог, который будет использоваться для хранения загруженных на сервер файлов. Если вы не установите его, то будет использоваться системный временный каталог по умолчанию.
Директива max_file_uploads позволяет устанавливать максимальное количество файлов, которые могут быть загружены на сервер за один раз. По умолчанию это 20
Создание формы загрузки
Сделаем HTML-форму для загрузки файла на сервер:
Пример
Обратите внимание на правила, которых следует придерживаться для приведенной выше HTML-формы:
Затем мы выводим поле файла, которое позволяет нам выбрать файл с компьютера:
Форма выше отправляет данные в файл-обработчик с именем «upload.php», который мы создадим дальше.
Создание сценария загрузки файла
Итак, создадим файл upload.php со следующим содержимым:
upload.php
Рассмотрим объявленные переменные в сценарии PHP:
Примечание: Файлы будут загружены в каталог «uploads/», поэтому вам нужно создать его в каталоге, в котором находится файл «upload.php».
Проверка существования файла
Ограничение размера файла
У каждого объекта файла есть свои параметры, которые мы можем получить:
$_FILES[‘file’][‘name’] : фактическое имя загруженного файла
$_FILES[‘file’][‘type’] : MIME-тип загружаемого файла, например, image/jpeg
$_FILES[‘file’][‘size’] : размер загружаемого файла в байтах
$_FILES[‘file’][‘tmp_name’] : имя временного файла, сохраненного на сервере
$_FILES[‘file’][‘error’] : код ошибки, связанной с загрузкой этого файла
Ограничение типа файла
Полный скрипт загрузки файла
Пример
Как отмечалось выше, при отправке файла на сервер он сначала загружается во временное место, из которого затем с помощью функции move_uploaded_file() он перемещается в созданный нами каталог сервера (мы прописали его в файле php.ini).
Функция move_uploaded_file() принимает два параметра — путь к загруженному временному файлу и путь, куда надо поместить загруженный файл.
Мы также используем функцию htmlspecialchars() для кодирования всех специальных символов HTML в отправленном нам файле.