php скрипт загрузки изображения на сайт php
Пошаговая инструкция по реализации загрузки файлов на сервер без перезагрузки страницы на PHP + Javascript
Проблема
Недавно я столкнулся с вполне, на мой взгляд, распространённой задачей: нужно обеспечить пользователю возможность загрузить на сервер любое число, скажем, картинок с комментарием к каждой из них в рамках одного интерфейса. В моём случае это было: фото товара, его описание и количество. Для наглядности прикладываю скриншот интерфейса:
Идея и алгоритм решения
Так как описания и фотографии для получения конечного результата можно изменять очень много раз, решено было осуществить следующую схему работы: фотографии загружаются на сервер на одной при клике на фото-иконку, при этом в случае успеха сервер возвращает имя картинки, а при неуспехе — «error». Соответственно, в случае успеха, фото-иконка заменяется на миниатюру загруженного фото, а в скрытое поле формы соответствующей строки сохраняется её имя, а при неуспехе мы получаем фото-иконку и пустое скрытое поле формы соответствующей строки, отвечающее за имя фото. Текстовая же информация при изменении любого поля формы отправляется на сервер вся в формате массив [имяФото, описаниеДетали, количествоШт] — это наиболее универсально: один и тот же метод отвечает за полное обновление списка товаров при их редактировании или удалении. Как известно, AJAX не умеет отправлять файлы, поэтому реализуем процедуру загрузки с помощью обычной формы, в качестве target которой укажем скрытый фрейм, который и будет перезагружаться вместо страницы.
Практическая реализация
Итак, в нашем распоряжении HTML, PHP и Javascript. Поехали:
1. Верстаем на странице форму для загрузки фото. Она содержит только один input, который мы спрячем с помощью css:
2. Создадим на странице скрытый iframe, который и будет перезагружаться в результате отправки формы с файлом:
3. Верстаем таблицу товаров, с которой и будет работать пользователь:
3. Пишем PHP-код загрузки файла:
Мой проект на CodeIgniter, поэтому код вот такой, но в целом, суть в следующем: мы просто загружаем и переименовываем полученный из формы файл, если всё проходит успешно, выводим в наш iframe его имя, если нет — «error».
4. Пишем Javascript, который будет контролировать весь процесс:
Вот, собственно, и весь процесс.
Если возникнет такая необходимость, сделаю демо процесса отдельным блоком и прикреплю сюда ссылку, а так же дам исходники.
Загрузка файлов на сайт: PHP, AJAX, HTML5 и Drag’n’Drop
Скучные формы загрузки — прошлый век. HTML5 дает возможности, чтобы добавить Drag’n’Drop, а AJAX позволяет загружать файлы без обновления страницы.
Программисту нужно позаботиться о том, чтобы посетитель смог сделать это максимально удобно. Загрузить файл на сайт можно и с помощью обычной формы и обработчика на PHP, но с выходом HTML5 появились другие интересные возможности — в этой статье мы поговорим и о базовых функциях, и о нововведениях.
Загрузка файлов на PHP
Начать следует с создания формы:
Для тега мы указываются следующие атрибуты:
Во второй тег добавляется атрибут multiple и имя file[] — это позволит с помощью одного поля загрузить сразу несколько файлов. Также в коде присутствует div, в который позже будет выводиться сообщение.
Далее указываются стили CSS:
И вот как это выглядит:
Сначала нужно провести несколько проверок, и только потом перемещать файлы из временного хранилища непосредственно на сайт. Иначе может получиться так, что взломщики загрузят на сайт PHP-файлы и смогут их запустить, чтобы получить доступ к базе данных или к файловой системе сервера.
Вот как выглядит обработчик:
Если загрузка прошла успешно, создается массив разрешенных типов, по которому проверяется соответствие форматов. Затем, если валидация пройдена, с помощью функции move_uploaded_file файл перемещается из временного хранилища в указанную директорию.
Такой код хоть и работает, но он довольно примитивен и его нужно расширять:
В общем, стоит провести несколько дополнительных проверок, чтобы файлы не представляли угрозу для сайта и не валялись без дела.
Загрузка файлов на сайт с помощью AJAX
Если добавить возможности JavaScript, форму можно сделать полезнее и красивее. Например, можно будет загружать файлы через AJAX, а также добавить анимацию при перетаскивании:
Функция получает файлы с помощью объекта FormData, затем показывает сообщение, что началась загрузка, и начинает отправлять файл.
Вот как работает загрузка файлов на AJAX:
Заключение
Дальше с файлами можно делать все что угодно:
Это лишь малая часть возможностей PHP — подробнее узнать о них всех можно из курса «PHP-разработчик», в котором сильная теоретическая база закрепляется сложными, но интересными практическими задачами.
Пишет о программировании, в свободное время создает игры. Мечтает открыть свою студию и выпускать ламповые RPG.
PHP. Загрузка изображений на сервер
Итак, мы продолжаем обсуждать тему загрузки файлов на сервер. Если вы ещё не читали статью «Что необходимо учитывать при загрузке файлов на сервер», то рекомендую начать именно с неё.
В вышеуказанной статье мы обсудили общие нюансы загрузки файлов на сервер. А теперь пришло время программировать! В данном примере мы реализуем:
Предупреждаю сразу, рассматриваемый код будет без архитектурных изысков, поскольку он должен быть максимально понятным для начинающих.
Для начала определим, какие файлы и папки будут в нашем проекте:
Посмотрим на содержимое индекса.
Кода много, но, пожалуйста, не пугайтесь! Большая часть знакома вам из предыдущей статьи.
Соответственно, если форма была отправлена, мы сначала вызываем функцию can_upload. Если она подтвердила, что файл подходит нам по всем параметрам, то мы вызываем функцию make_upload. Иначе просто распечатываем сообщение об ошибке.
Здесь всё достаточно коротко и логично. Схема стандартная. Поэтому нас больше интересует, а что именно делают эти загадочные функции can_upload и make_upload!
Рассмотрим файл functions.php
Сначала всего пару слов про функцию make_upload, поскольку она проще. Обратите внимание на то, что мы перед именем файла вставляем mt_rand(0, 10000), т.е, случайное число от 0 до 10000. Делается это для того, чтобы у файла было уникальное имя. В противном случае, при загрузке двух картинок с одинаковыми именами, вторая заменит первую.
Кстати, если вы задались резонным вопросом, а где же закрывающий тег php в данном файле, значит, вы явно не читали статью «Ошибка headers already sent»!
Необходимые проверки
Основной же интерес для нас представляет функция can_upload.
Вот собственно говоря и всё! Скрипт надёжный, аккуратный и лаконичный.
А в следующей статье мы поговорим о том, как можно наложить на загружаемую картинку водяной знак. Рекомендую прочесть!
Безопасная загрузка изображений на сервер. Часть первая
В данной статье демонстрируются основные уязвимости веб-приложений по загрузке файлов на сервер и способы их избежать. В статье приведены самые азы, в врят-ли она будет интересна профессионалам. Но тем неменее — это должен знать каждый PHP-разработчик.
Различные веб-приложения позволяют пользователям загружать файлы. Форумы позволяют пользователям загружать «аватары». Фотогалереи позволяют загружать фотографии. Социальные сети предоставляют возможности по загрузке изображений, видео, и т.д. Блоги позволяют загружать опять же аватарки и/или изображения.
Часто загрузка файлов без обеспечения надлежащего контроля безопасности приводит к образованию уязвимостей, которые, как показывает практика, стали настоящей проблемой в веб-приложениях на PHP.
Проводимые тесты показали, что многие веб-приложения имеют множество проблем с безопасностью. Эти «дыры» предоставляют злоумышленникам обширные возможности совершать несанкционированные действия, начиная с просмотра любого файла на сервере и закачивания выполнением произвольного кода. Эта статья рассказывает об основных «дырах» безопасности и способах их избежать.
Код примеров, приведенных в этой статье, могут быть загружены по адресу:
www.scanit.be/uploads/php-file-upload-examples.zip.
Если Вы хотите их использовать, пожалуйста удостоверьтесь, что сервер, который Вы используете, не доступен из Интернета или любых других публичных сетей. Примеры демонстрируют различные уязвимости, выполнение которых на доступном извне сервере может привести к опасным последствиям.
Обычная загрузка файла
Загрузка файлов, обычно состоит из двух независимых функций – принятие файлов от пользователя и показа файлов пользователю. Обе части могут быть источником уязвимостей. Давайте рассмотрим следующий код (upload1.php):
Обычно пользователи будут загружать файлы, используя подобную форму:
form name =»upload» action =»upload1.php» method =»POST» ENCTYPE =»multipart/form-data» >
Select the file to upload: input type =»file» name =»userfile» >
input type =»submit» name =»upload» value =»upload» >
form >
Злоумышленник данную форму использовать не будет. Он может написать небольшой Perl-скрипт (возможно на любом языке – прим. преводчика), который будет эмулировать действия пользователя по загрузке файлов, дабы изменить отправляемые данные на свое усмотрение.
В данном случае загрузка содержит большую дыру безопасности: upload1.php позволяет пользователям загружать произвольные файлы в корень сайта. Злоумышленник может загрузить PHP-файл, который позволяет выполнять произвольные команды оболочки на сервере с привилегией процесса веб-сервера. Такой скрипт называется PHP-Shell. Вот самый простой пример подобного скрипта:
Если этот скрипт находится на сервере, то можно выполнить любую команду через запрос:
server/shell.php?command=any_Unix_shell_command
Более продвинутые PHP-shell могут быть найдены в Интернете. Они могут загружать произвольные файлы, выполнять запросы SQL, и т.д.
Исходник Perl, показанный ниже, загружает PHP-Shell на сервер, используя upload1.php:
Этот скрипт использует libwwwperl, который является удобной библиотекой Perl, эмулирующей HTTP-клиента.
И вот что случится при выполнении этого скрипта:
POST /upload1.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Length: 156
Content-Type: multipart/form-data; boundary=xYzZY
—xYzZY
Content-Disposition: form-data; name=»userfile»; filename=»shell.php»
Content-Type: text/plain—xYzZY—
HTTP/1.1 200 OK
Date: Wed, 13 Jun 2007 12:25:32 GMT
Server: Apache
X-Powered-By: PHP/4.4.4-pl6-gentoo
Content-Length: 48
Connection: close
Content-Type: text/html
File is valid, and was successfully uploaded.
После того, как мы загрузили shell-скрипт, можно спокойно выполнить команду:
$ curl localhost/uploads/shell.php?command=id
uid=81(apache) gid=81(apache) groups=81(apache)
cURL – command-line клиент HTTP, доступный на Unix и Windows. Это очень полезный инструмент для того, чтобы проверить веб-приложения. cURL может быть загружен от curl.haxx.se
Проверка Content-Type
Приведенный выше пример редко когда имеет место. В большинстве случаев программисты используют простые проверки, чтобы пользователи загружали файлы строго определенного типа. Например, используя заголовок Content-Type:
Пример 2 (upload2.php):
В этом случае, если злоумышленник только попытается загрузить shell.php, наш код будет проверять MIME-тип загружаемого файла в запросе и отсеивать ненужное.
POST /upload2.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 156
—xYzZY
Content-Disposition: form-data; name=»userfile»; filename=»shell.php»
Content-Type: text/plain—xYzZY—
HTTP/1.1 200 OK
Date: Thu, 31 May 2007 13:54:01 GMT
Server: Apache
X-Powered-By: PHP/4.4.4-pl6-gentoo
Content-Length: 41
Connection: close
Content-Type: text/html
Sorry, we only allow uploading GIF images
Пока неплохо. К сожалению, есть способ обойти эту защиту, потому что проверяемый MIME-тип приходит вместе с запросом. В запросе выше он установлен как «text/plain» (его устанавливает браузер – прим. переводчика). Ничего не мешает злоумышленнику установить его в «image/gif», поскольку с помощью эмуляции клиента он полностью управляет запросом, который посылает (upload2.pl):
И вот что получится.
POST /upload2.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 155
—xYzZY
Content-Disposition: form-data; name=»userfile»; filename=»shell.php»
Content-Type: image/gif—xYzZY—
В итоге, наш upload2.pl подделывает заголовок Content-Type, заставляя сервер принять файл.
Проверка содержания файла изображения
Вместо того, чтобы доверять заголовку Content-Type, разработчик PHP мог бы проверять фактическое содержание загруженного файла, чтобы удостовериться, что это действительно изображение. Функция PHP getimagesize() часто используется для этого. Она берет имя файла как аргумент и возвращает массив размеров и типа изображения. Рассмотрим пример upload3.php ниже.
Теперь, если нападавший попытается загрузить shell.php, даже если он установит заголовок Content-Type в «image/gif», то upload3.php все равно выдаст ошибку.
POST /upload3.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 155
—xYzZY
Content-Disposition: form-data; name=»userfile»; filename=»shell.php»
Content-Type: image/gif—xYzZY—
HTTP/1.1 200 OK
Date: Thu, 31 May 2007 14:33:35 GMT
Server: Apache
X-Powered-By: PHP/4.4.4-pl6-gentoo
Content-Length: 42
Connection: close
Content-Type: text/html
Sorry, we only accept GIF and JPEG images
Можно подумать, что теперь мы можем пребывать в уверенности, что будут загружаться только файлы GIF или JPEG. К сожалению, это не так. Файл может быть действительно в формате GIF или JPEG, и в то же время PHP-скриптом. Большинство форматов изображения позволяет внести в изображение текстовые метаданные. Возможно создать совершенно корректное изображение, которое содержит некоторый код PHP в этих метаданных. Когда getimagesize() смотрит на файл, он воспримет это как корректный GIF или JPEG. Когда транслятор PHP смотрит на файл, он видит выполнимый код PHP в некотором двоичном «мусоре», который будет игнорирован. Типовой файл, названный crocus.gif содержится в примере (см. начало статьи). Подобное изображение может быть создано в любом графическом редакторе.
Итак, создадим perl-скрипт для загрузки нашей картинки:
Этот код берет файл crocus.gif и загружает это с названием crocus.php. Выполнение приведет к следующему:
Теперь нападавший может выполнить uploads/crocus.php и получить следущее:
Как видно, транслятор PHP игнорирует двоичные данные в начале изображения и выполняет последовательность » » в комментарии GIF.
Проверка расширения загружаемого файла
Читатель этой статьи мог бы задаться вопросом, почему мы просто не проверяем расширение загруженного файла? Если мы не позволим загружать файлы *.php, то сервер никогда не сможет выполнить этот файл как скрипт. Давайте рассмотрим и этот подход.
Мы можем сделать черный список расширений файла и проверить имя загружаемого файла, игнорируя загрузку файла с выполняемыми расширениями (upload4.php):
POST /upload4.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 14835
—xYzZY
Content-Disposition: form-data; name=»userfile»; filename=»crocus.php»
Content-Type: image/gif
GIF89(. skipping binary data. )
—xYzZY—
HTTP/1.1 200 OK
Date: Thu, 31 May 2007 15:19:45 GMT
Server: Apache
X-Powered-By: PHP/4.4.4-pl6-gentoo
Content-Length: 36
Connection: close
Content-Type: text/html
We do not allow uploading PHP files
POST /upload4.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 14835
—xYzZY
Content-Disposition: form-data; name=»userfile»; filename=»crocus.gif»
Content-Type: image/gif
GIF89(. skipping binary data. )
—xYzZY—
Теперь, если мы запросим загруженный файл, то он не будет выполнен сервером:
Комментарии переводчика:
В случае загрузки картинок самым лучшим способом являются не указанные действия, а сохранение файла с расширением, которое получается в результате выполнения функции getimagesize(). В большинстве случаев именно так и происходит. Стоит добавить, что желательно сделать приведение файла к конкретному формату, например jpeg. При приведении метаданные картинки (насколько мне известно) потеряются, обеспечив практически гарантируемую безопастность.
Загружаем фото на сайт php
Загружаем фото на сайт php
Форма для загрузки фото php
У нас стандартная форма для отправки данных выглядит таким образом:
И если мы её выведем, то никакой кнопки загрузить фото мы не найдем:
Поэтому нам немного нужно её изменить!
Добавляем в форму enctype=»multipart/form-data»
И тип файла в input меняем с «text» на «file»
Вот что у нас должно получиться:
Элементарная загрузка фото на сайт php
И далее нам нужно разобраться с php скриптом, который загрузит фото на сайт!
Внимание! Не забываем! Что загрузка фото на сервер не безопасна и надо сделать множество проверок, чтобы убедиться в том, что этот файл безопасен.
Но мы сейчас. просто пытаемся разобраться в механизме загрузки фото на сервер
В сети есть различные способы загружать, я расскажу, каким пользуюсь я!
Что нам понадобится для загрузки фото на сервер php
При отправке выше приведенной формы с загрузкой фото, изображение автоматически попадает во временную папку, которая должна быть определена в настройках сервера. → если же изображение не удастся загрузить во временную папку, то php вам об этом сообщит! Но мы предполагаем, что сервер настроен правильно! Покупайте только правильный хостинг!, где сервер настроен правильно изначально, но если это и не так, то вы всегда сможете почитать о нём на нашем сайте!
Функция для перемещения изображения
Если файл загружен, то нам нужно переместить наш файл в конечную папку, где и будет находиться файл изображения до его удаления.
Скачиваем со страницы все скрипты Не забудь сказать спасибо!
Где находится временная папка для загрузки фото на сервере
Заходим в наш «DirectAdmin» → нам нужна строка настройки php:
Данная папка недоступна по адресу «http»
Где находится временная папка для загрузки фото на сервере
Проверка типа изображения
Для того, чтобы проверить является ли данный файл изображением надо получить данные из загружаемого файла это функция getimagesize
Проверяем на тип изображения:
[3] => width=»1920″ height=»1080″
Её нужно разделить с помощью функции explode
Название и расширение сохраняемого файла «test.$mime[1]»
Это лишь один пример того, как должна выглядеть проверка загружаемого файла! И еще нужно сделать несколько проверок, например, на вес фото! + На наличие вредоносного кода, но об этом мы поверим уже в другой раз!
Поисковые запросы на тему фото php.
Иногда встречаются такие поисковые запросы, что и не понимаешь, что вообще человек имеет ввиду, спрашивая это:
как в php подключить картинку к сайту
Это загрузить на сайт, что мы всю страницу пытались рассказать.
Поместить html код картинки в переменную:
Потом вывести с помощью echo.
Либо так без переменной:
Сообщение системы комментирования :
Форма пока доступна только админу. скоро все заработает. надеюсь.