- 1. Использование PHP функции file_get_contents()
- 2. Использование PHP функции fsockopen()
- 3. Использование CURL
- §1. Общие принципы
- §2. Правила безопасности
- §3. Конфигурация php.ini
- §4. Загрузка картинок из формы
- §5. Загрузка изображения по ссылке
- §6. Настройка выбора нескольких файлов
- Скопировать одну картинку с помощью php (Задача №1)
- Скопировать все картинки со страницы с помощью php (Задача №2)
- Читайте также похожие статьи:
Чтобы сохранить изображение с заданного URL-адреса в PHP, вы сначала должны скачать его, а затем сохранить у себя на сервере.
1. Использование PHP функции file_get_contents()
2. Использование PHP функции fsockopen()
Чтобы получить изображение с помощью функции fsockopen() , вам необходимо указать имя хоста оставшуюся часть адреса, по которому хранится изображение. Для лучшего понимания вот пример функции, которая возвращает изображение:
3. Использование CURL
Вы можете использовать следующий код, чтобы вызвать функцию для получения изображения:
После скачивания изображения вам нужно сохранить его, просто выполнив сохранение в файл по заданному пути.
Вы можете использовать следующий код:
Данная публикация представляет собой перевод статьи « PHP Save Image From URL » , подготовленной дружной командой проекта Интернет-технологии.ру
В этой статье подробно разберём механизм загрузки изображений на сервер с помощью PHP не прибегая к сторонним компонентам и фреймворкам. Научимся безопасно загружать изображения не только с локальной машины пользователя, но и удалённые файлы по ссылке. Все примеры кода я буду писать в процедурном стиле, дабы вы быстрее могли читать код, а не перескакивать с одного метода на другой. Руководство полностью авторское и не претендует на какую-либо академичность изложения.
§1. Общие принципы
Всю последовательность загрузки изображения на сервер можно отобразить следующим образом: настройка php.ini → получение файла → проверка безопасности → валидация данных → сохранение на диск. Процесс загрузки картинки с компьютера пользователя или по URL ничем не отличаются, за исключением способа получения изображения и его сохранения. Общая схема загрузки картинки на сервер выглядит следующим образом:
Для валидации картинки по URL мы будем использовать функцию getimagesizefromstring(), т. к. cURL скачает её в переменную для дальнейших манипуляций.
Поскольку мы загружаем изображения на сервер, то хорошо было бы проверять их определённые параметры: ширину, высоту, тип картинки, размер файла в байтах. Это зависит от логики вашего приложения, но для наглядности в этом руководстве мы проверим все вышеописанные параметры.
§2. Правила безопасности
Безопасность загрузки изображений сводится к недопущению попадания на сервер чужеродного кода и его выполнения. На практике загрузка картинок наиболее уязвимое место в PHP-приложениях: попадание shell-скриптов, запись вредоносного кода в бинарные файлы, подмена EXIF-данных. Для того, чтобы избежать большинства методов взлома нужно придерживаться следующих правил:
Если есть чем дополнить «Правила безопасности», тогда оставляйте свои замечания или ссылки на статьи по безопасности в комментариях к этому руководству, а я опубликую их в этом параграфе.
§3. Конфигурация php.ini
PHP позволяет внести определённые конфигурационные значения в процесс загрузки любых файлов. Для этого необходимо в файле php.ini найти блоки «Resource Limits», «Data Handling» и «File Uploads», а затем отредактировать, по необходимости, следующие значения:
Исходя из указанных значений, пользователь не сможет за один раз загрузить больше десяти файлов, причём каждый файл не должен превышать 5 Мбайт. Параметры из блока «Resource Limits» больше нужны для загрузки удалённого файла, т. к. с помощью cURL мы будем скачивать содержимое в переменную и проверять её по нужным нам критериям, а для этого необходимо дополнительное время и память.
50 Мбайт памяти. Кроме того, нам нужно знать максимальное время загрузки одного файла с локальной машины и по ссылке, дабы установить достаточное время выполнения скрипта в max_execution_time и не пугать пользователей ошибками.
§4. Загрузка картинок из формы
Сейчас мы не будем рассматривать загрузку нескольких файлов на сервер, а разберём лишь саму механику загрузки на примере одного файла. Итак, для загрузки картинки с компьютера пользователя необходимо с помощью HTML-формы отправить файл PHP-скрипту методом POST и указать способ кодирования данных enctype="multipart/form-data" (в данном случае данные не кодируются и это значение применяется только для отправки бинарных файлов). С формой ниже мы будем работать дальше:
Для поля выбора файла мы используем имя name="upload" в нашей HTML-форме, хотя оно может быть любым. После отправки файла PHP-скрипту file-handler.php его можно перехватить с помощью суперглобальной переменной $_FILES[‘upload’] с таким же именем, которая в массиве содержит информацию о файле:
Не всем данным из $_FILES можно доверять: MIME-тип и размер файла можно подделать, т. к. они формируются из HTTP-ответа, а расширению в имени файла не стоит доверять в силу того, что за ним может скрываться совершенно другой файл. Тем не менее, дальше нам нужно проверить корректно ли загрузился наш файл и загрузился ли он вообще. Для этого необходимо проверить ошибки в $_FILES[‘upload’][‘error’] и удостовериться, что файл загружен методом POST с помощью функции is_uploaded_file(). Если что-то идёт не по плану, значит выводим ошибку на экран.
Для того, чтобы злоумышленник не загрузил вредоносный код встроенный в изображение, нельзя доверять функции getimagesize(), которая также возвращает MIME-тип. Функция ожидает, что первый аргумент является ссылкой на корректный файл изображения. Определить настоящий MIME-тип картинки можно через расширение FileInfo. Код ниже проверит наличие ключевого слова image в типе нашего загружаемого файла и если его не окажется, выдаст ошибку:
На данном этапе мы уже можем загружать абсолютно любые картинки на наш сервер, прошедшие проверку на MIME-тип, но для загрузки изображений по определённым характеристикам нам необходимо валидировать их с помощью функции getimagesize(), которой скормим сам бинарный файл $_FILES[‘upload’][‘tmp_name’]. В результате мы получим массив максимум из 7 элементов:
Для дальнейшей валидации изображения и работы над ним нам необходиом знать только 3 значения: ширину, высоту и размер файла (для вычисления размера применим функцию filesize() для бинарного файла из временной папки).
После всех проверок мы можем с уверенностью переместить наш загружаемый файл в какую-нибудь папку с картинками. Делать лучше это через функцию move_uploaded_file(), которая работает в безопасном режиме. Перед перемещением файла нельзя забыть сгенерировать случайное имя и расширение из типа изображения для нашего файла. Вот так это выглядит:
На этом загрузка изображения завершена. Для более удобной загрузки файлов можете использовать класс UploadedFile из пакета Symfony HttpFoundation, который является обёрткой для $_FILES и также сохраняет файл через move_uploaded_file().
§5. Загрузка изображения по ссылке
Для загрузки изображения по ссылке нам понадобиться библиотека cURL, которая работает с удалёнными ресурсами. С помощью неё мы скачаем контент в переменную. С одной стороны может показаться, что для этих целей подойдёт file_get_contents(), но на самом деле мы не сможем контролировать объём скачиваемых данных и нормально обрабатывать все возникшие ошибки. Для того, чтобы cURL корректно скачал данные нам нужно: разрешить следовать перенаправлениям, включить проверку сертификата, указать максимальное время работы cURL (формируется за счёт объёма скачиваемых данных и средней скорости работы с ресурсом). Как правильно скачать файл в переменную показано ниже с необходимыми параметрами:
Если всё прошло успешно и cURL уложился в 60 секунд, тогда содержимое по ссылке будет скачано в переменную $raw. Кроме того, функция curl_getinfo() вернёт информацию о проделанном запросе, откуда мы можем получить дополнительную информацию для анализа работы с удалёнными ресурсами:
Дальше нам нужно проверить нет ли ошибок в curl_errno() и удостовериться, что ресурс отдаёт равный 200, иначе мы скажем, что по такому-то URL ничего не найдено. После всех проверок переменную $raw передаём в getimagesizefromstring() и работаем уже по отработанной схеме как в случае с загрузкой картинок из формы.
Для сохранения изображения на диск можно воспользоваться file_put_contents(), которая запишет контент в файл. Новое имя файла мы создадим через функцию md5(), а расширение сделаем из image_type_to_extension(). Теперь мы можем загружать любые картинки по ссылке.
§6. Настройка выбора нескольких файлов
В этом параграфе разберём способы загрузки нескольких изображений за один раз с локальной машины пользователя и по удалённым ссылкам. Для отправки ссылок мы задействуем $_POST и передадим ей все данные с помощью тега textarea. Для загрузки файлов из формы мы продолжим дальше работать с $_FILES. Наша новая HTML-форма будет немного отличаться от старой.
В конец имени поля выбора файла name="upload[]" добавились фигурные скобки и аттрибут multiple, который разрешает браузеру выбрать несколько файлов. Все файлы снова загрузятся во временную папку, если не будет никаких ошибок в php.ini . Перехватить их можно в $_FILES, но на этот раз суперглобальная переменная будет иметь неудобную структуру для обработки данных в массиве. Решается эта задача небольшими манипуляциями с массивом:
Для загрузки нескольких картинок по URL передадим наши ссылки через textarea с именем name="upload", где их можно указать через пробел или с новой строки. Функция preg_split разберёт все данные из $_POST[‘upload’] и сформирует массив, по которому нужно пройтись циклом и каждый валидный URL отправить в обработчик.
Вы можете улучшить форму для загрузки изображений, например, воспользоваться библиотекой FineUploader или jQuery FileUpload, чтобы настроить выбор картинок с определённым расширением.
Здравствуй уважаемый читатель блога LifeExample, иногда случается так, что вручную сохранить картинки со страницы какого либо ресурса, немного накладно. Если картинок много, то задачу автоматического сохранения их в файл можно переложить на плечи PHP. Статья php сохранение картинки, обещает быть очень короткой, и нести в себе минимум лишней информации.
Для того чтобы нам с помощью php скрипта можно было осуществить сохранение картинки, нужно изучить предназначение функции copy(). Не трудно догадаться, что данная функция что-то копирует, а именно она занимается копированием и сохранением файлов, в том числе и картинок. В параметры этой функции нужно передать путь к картинке, которую нужно сохранить и название, которое получит сохраненная картинка.
Скопировать одну картинку с помощью php (Задача №1)
Допустим мы имеем url нужного изображения:
Мы хотим скопировать ее себе на сервер и дать имя «some_image.jpg»
Передадим в функцию copy, наши параметры
Запускаем скрипт, и смотрим на содержимое директории, из которой он был вызван. Если все прошло гладко, то мы обнаружим сохраненную картинку.
Скопировать все картинки со страницы с помощью php (Задача №2)
Зная как сохранить одну картинку, не сложно написать парсер всей страницы, с последующим сохранением найденных изображений. Для этого советую воспользоваться материалом изложенном в статье: «Регулярные выражения в PHP«.
Сразу приведу код рабочего php скрипта для сохранения всех картинок со страницы.
Скрипт с помощью функции curl_init() получает содержимое нужной страницы и регулярным выражением выбирает все картинки с расширением png и jpg. Далее для каждой из картинок создается определенная ссылкой структура папок, и функцией copy() сохраняется на наш сервер.
Внимание! При использовании функции curl_init() на денвере, не редко вы можете столкнуться с ошибкой ее использования. Если это случилось, то прочтите решение этой проблемы в статье Fatal error: Call to undefined function curl_init()
Результатом работы данного скрипта вы увидите: полностью скопированную структуру картинок и папок с сайта источника, на вашем сервере. Кстати говоря, хоть и статья «php сохранение картинки«, подразумевает сохранение только картинок, но с помощью приведенного скрипта, можно сохранить все файлы с сайта, немного изменив код. Если вас заинтересует, я напишу о том как это сделать.
Читайте также похожие статьи:
Чтобы не пропустить публикацию следующей статьи подписывайтесь на рассылку по E-mail или RSS ленту блога.