Позже или ранее в жизни веб-разработчиков вам придется иметь дело с файлами и изображениями, загруженными пользователями.
Общие вопросы:
Как загрузить?
современные веб-браузеры и методы позволяют несколько способов загрузки файлов, предоставленных пользователем на мой сервер. Каковы наилучшие практики и что я должен учитывать?
Как я могу обработать?
После завершения загрузки, что мне нужно знать о безопасности и дальнейшей обработки файлов
Как сохранить и доставить?
Есть ли рекомендации по хранению загруженных файлов?
отказ от ответственности: я поставил почти 30 минут на следующий ответ, первоначальный вопрос был удален, поэтому я решил задать общие вопросы, с которыми может столкнуться пользователь при работе с файлами, предоставленными пользователем. См. Мой ответ, вы можете вносить свой вклад и добавлять свои идеи и опыт
Для каждого из этих этапов нет «наилучшего» способа, но существует целая куча установленных способов и лучших практик среди множества техник и библиотек, которые могут помочь вам достичь удобной загрузки, безопасности и скорости.
По другому вопросу, который, к сожалению, был удален, я написал этот небольшой путеводитель.
Файл или изображение, внесенное пользователем, проходит через несколько этапов его жизни:
Это будет описано во всех шагах и, если возможно, привести примеры
1. Загрузить
Современные веб-браузеры предлагают несколько способов загрузки файла.
Самый простой способ – создать форму с простым <input type="file" name="userFile" />
. Как только форма будет отправлена, файл будет отправлен с использованием POST, и к нему можно получить доступ с суперкоммулятором $ _FILES в PHP
1.1. Простая форма в HTML
<form action="upload.php" method="post" enctype="multipart/form-data"> <input type="file" name="userFile1" /> <input type="file" name="userFile2" /> <input type="submit" value="upload files" /> </form>
Когда форма отправляется, POST-запрос отправляется в upload.php. Этот вид загрузки не очень удобен для пользователя. Ваш пользователь не увидит никакого прогресса в загрузке, и загрузка нескольких файлов будет больно
1.2. Загрузка javascript ajax
В этом решении POST выполняется асинхронно с javascript
http://www.saaraan.com/2012/05/ajax-image-upload-with-progressbar-with-jquery-and-php
1.3. Загрузка HTML 5
современные браузеры поддерживают HTML5, что позволяет очень красиво и удобно загружать маски с индикатором выполнения и предварительным просмотром – граница – это ваше собственное творчество
Например, мне очень нравится эта демонстрация: http://html5demos.com/dnd-upload
На стороне сервера
Независимо от того, какую из тех технологий загрузки вы решите использовать, загрузка будет в HTTP POST отправлена на ваш скрипт. Вся дальнейшая обработка будет выполняться на сервере.
PHP копирует файл во временный путь ( upload_tmp_dir )
Есть несколько других настроек, связанных с загрузкой, которые вы можете настроить в своем php.ini или на лету с помощью ini_set : http://php.net/manual/en/ini.core.php#ini.sect.file- добавления
upload.php
<pre> <?php print_r( $_FILES );
Вот как выглядит $_FILES
после успешной загрузки.
У каждого файла есть собственный индекс
Array ( [userFile1] => Array ( [name] => i_love_ponies.png [type] => image/png [size] => 42233 [tmp_name] => /tmp/_x123tfsdayx134 [error] => 0 ) [userFile2] => Array ( [name] => ponies_run_my_server.png [type] => image/png [size] => 12325 [tmp_name] => /tmp/_x3123asdad3ssy [error] => 0 ) )
Несколько дополнительных советов
Если вы ожидаете больших файлов, рассмотрите тайм-ауты выполнения веб-сервера и php. Если загрузка занимает 10 минут, вы не хотите, чтобы ваши пользователи оказались в ошибке.
В PHP вы можете увеличить max_execution_time
2. Проверка
Вопросы, которые вы можете задать
Должен ли я разрешать только определенные файлы – какой файл я получу?
тип, который вы находите в массиве $_FILES
задается браузером. Если вы хотите быть уверенным, какой тип был загружен, вы можете использовать расширение fileinfo для PHP.
В этом примере будет проверяться успех самой загрузки и записать файлы разрешенных типов в новый массив для последующей обработки
$allowedTypes = array( 'image/png' 'image/gif' 'image/jpeg' ); $useFiles = array(); $finfo = new finfo(FILEINFO_MIME_TYPE); foreach ( $_FILES as $index => $file ) { if ( $file['error'] === UPLOAD_ERR_OK ) { $type = $finfo->file( $file['tmp_name'] ); if ( in_array( $type, $allowedTypes ) ) { $useFiles[$index] = $file; } } }
Я хочу установить максимальный размер файла – какой размер?
В этом случае вы можете смело полагаться на значение $_FILES['key']['size']
, размер которого равен байтам. Вы не должны просто полагаться на ограничение размера файла на стороне клиента
если говорить об изображениях, хочу ли я масштабировать или создавать миниатюры – каковы размеры изображения?
Взгляните на getimagesize, чтобы определить размеры изображения
3. Обработка
Прежде чем сохранять файл в его конечном месте, вы можете захотеть обработать его. Это время, когда вы можете
Обычными библиотеками, используемыми для обработки изображений, являются gd lib и imagick . лично я предпочитаю gd lib. Это немного более ручная работа, но она быстрее и поставляется с большинством установок по умолчанию или проста для установки дополнительно. Imagemagick изначально имеет очень большой пул функций обработки изображений
4. Сохранение данных
Теперь пришло время поговорить о хранении. Сначала сохраните способ скопировать временный файл во временное или окончательное местоположение.
Вы должны использовать move_uploaded_file
move_uploaded_file( $useFiles['tmp_name'], $destination );
Опять же, для хранения нет «лучшего способа», это зависит от вашей среды, файлов и использования. Я расскажу о нескольких
4.1. файловая система сервера
Это, вероятно, самый используемый и простой способ хранения ваших файлов. Вы можете просто ставить файлы статически с уже запущенным веб-сервером. Обычно это место в корне вашего документа.
Чтобы сделать вашу жизнь проще, вы можете сохранить имя файла в базу данных – предпочтительнее ссылаться или ссылаться на связанные данные, такие как пользователь или местоположение.
Вы не должны сохранять все файлы в одной папке по разным причинам.
Вам нужно будет создать уникальное имя для каждого файла, иначе вы замените существующий файл новым. Также обычным файловым системам становится все медленнее искать с увеличением количества файлов в узле. Это приведет к медленному времени отклика, когда файл запрашивается для доставки.
Вы можете сохранить его в папку для каждого пользователя
/uploaded/user-id/file.jpg
Если вы ожидаете большого количества файлов на пользователя, вы можете разделить контрольную сумму имени файла, чтобы получить более глубокую структуру папок
например
$path = $_SERVER['DOCUMENT_ROOT'] . '/uploaded/' . $userId . '/' . chunk_split( md5( $useFiles['index']['name'] ), 12, '/' );
приведет к
/var/www/htdocs/uploaded/1/97e262286853/d52aa8c58eb7/f0431f03/
4.2. База данных
Вы можете хранить ваши файлы в базе данных MySQL, используя тип blob. Я не рекомендую это вообще
4,3. Сеть доставки контента
Если вы ожидаете много трафика по всему миру, вы можете захотеть сохранить ваши файлы на CDN, например Amazon S3, с Cloudfront.
S3 – дешевое надежное хранилище для файлов размером до 5 ТБ (насколько мне известно)
http://www.9lessons.info/2012/08/upload-files-to-amazon-s3-php.html
Вам не придется беспокоиться о резервных копиях файлов, доступном размере жесткого диска, скорости доставки и т. Д. И т. Д. Cloudfront добавляет слой CDN поверх S3 с крайними местоположениями по всему миру