Загрузка изображений на сервер и изменение размера изображения на PHP

свойства изображения

Сегодня я хочу рассказать о реализации довольно популярной задачи. Во-первых, это загрузка изображения на сервер. А во-вторых, это изменение размера изображения. Также рассмотрим поворот и изменение качества.

Скачать исходный код себе на компьютер!

Немного теории по загрузке изображений на сервер средствами PHP

Вы не можете сразу загрузить файл в свою папку. Вначале он загружается во временную директорию сервера, а затем обрабатывается с помощью PHP интерпритатора. По окончанию сессии временный файл автоматически удаляется. То есть, мы вначале забрасываем файл во временную папку, а затем перекладываем в нужную.

$_FILES это массив загруженных файлов. Он имеет параметры (на примере файла picture):

$_FILES[' picture ']['name'] – настоящее имя файла. Например: image.jpg.

Бесплатный курс по PHP программированию

Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC

В курсе 39 уроков | 15 часов видео | исходники для каждого урока

Получить курс сейчас!

$_FILES[' picture ']['size'] – размер файла в байтах.

$_FILES[' picture ']['type'] – MIME-тип загруженного файла. Например: image/gif, image/png, image/jpeg.

$_FILES[' picture ']['tmp_name'] – содержит имя файла во временном каталоге, например: /tmp/phpV3b3qY. Именно этот параметр и используется для перемещения файлов после загрузки.

$_FILES[' picture ']['error'] – код ошибки.

Подготовка

Для начала нам нужна форма для загрузки. Возьмём простейшую форму.

Параметр enctype="multipart/form-data" обязателен для такой формы. Тег <input type="file" name="picture"> отвечает за поле для ввода имени файла, который загружается на сервер.

Также нам потребуется обработчик события – загрузки файла. Вначале у нас будет одна настройка – путь сохранения изображения. Можно указывать как прямой, так и относительный путь. В случае POST запроса обработчик попробует осуществить загрузку файла по указанному пути. Скрипт сообщит о результате загрузки – удачна она или нет.

Функция copy, как вы наверно догадались, отвечает за копирование файла из одного место в другое. Мы копируем файл из временной папки сервера в нужную, сохранив имя файла.

Договоримся, что и форма и её обработчик будут находиться в одном файле – upload.php.

Итого имеем простой, но рабочий скрипт. Его можно забросить на хостинг, создать папку i и потренироваться с загрузкой файлов.

свойства изображения

Проверки

Любая форма представляет для сайта опасность. И особенно форма загрузки файлов. Злоумышленник может загрузить скрипт и выполнить его на сервере. Поэтому необходимо озаботиться безопасностью.

Самые простые и обязательные проверки – на размер и тип файла. Для этого укажем допустимые типы и размер.

Тип файла укажем в виде массива:

а размер файла в байтах:

Проверяем тип файла. В случае недопустимого типа прекращаем работу скрипта и выводим соответствующее уведомление. Функция in_array проверяет присутствие значения в массиве.

свойства изображения

Проверяем размер файла. В случае недопустимого размера прекращаем работу скрипта и выводим соответствующее уведомление.

свойства изображения

Итого получаем такой скрипт. Скрипт рабочий, можно баловаться. Немного забегая вперёд, добавим также параметр $tmp_path – путь к папке временных файлов.

Изменение размеров изображений PHP

Приступим к самому интересному, а именно изменению размеров изображения с помощью PHP. Для этого напишем функцию resize. Сделаем также возможным изменять качество изображения и поворачивать его.

Размер изображения будем подставлять исходя из параметра. Это будет либо эскиз ($type = 1), либо большое изображение ($type = 2).

Итак, шапка функции у нас получилась такая:

По умолчанию подставляем размеры эскиза, а поворот и качество по умолчанию не используются. Пойдём дальше.

Устанавливаем ограничение размера изображения по ширине. Функцию можно сделать более абстрактной, если задавать эти значения в параметрах, а также сделать возможным ограничение и по высоте. Однако в данном случае нам не нужна такая универсальность.

Устанавливаем качество изображения по умолчанию (при $quality = null) равным 75%.

Далее создаём изображение для дальнейших преобразований. Для создания используем функцию в зависимости от типа файла (jpg, png или gif). Функции создания называются очень лаконично imagecreatefrom + тип файла.

Если указан параметр $rotate, выполняем поворот изображения. Делаем это с помощью функции rotate(), параметрами которой являются: изображение, градусы, фон изображения для закрашивания пустых областей, образованных при повороте. Для того чтобы пустые области не возникали, поворачиваем изображение на угол в 90, 180, 270 градусов.

Бесплатный курс по PHP программированию

Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC

В курсе 39 уроков | 15 часов видео | исходники для каждого урока

Получить курс сейчас!

Далее определяем высоту и ширину изображения с помощью функций imagesx и imagesy.

В зависимости от типа (эскиз или большое изображение) устанавливаем ограничение по ширине.

Далее, если ширина изображения больше максимальной, проводим преобразования. Иначе просто сохраняем изображение и очищаем память. Сохраняем изображение с помощью функции imagejpeg. В данном примере, рассмотрено сохранение только в формате jpg, однако функционал всегда можно расширить. Удаляем изображения из памяти с помощью функции imagedestroy.

В качестве результата работы функции возвращаем имя файла. Оно нам ещё понадобится.

Вернёмся к преобразованию. Вначале вычисляем пропорции изображения и размеры преобразованного изображения.

Далее создаём пустую картинку (функция imagecreatetruecolor) с шириной и высотой, полученными на прошлом шаге.

И копируем исходное изображение ($src) в только что созданное ($dest), изменяя его размеры. Функция imagecopyresampled делает это с пересэмплированием, что улучшает качество.

И наконец, сохраняем полученное изображение и очищаем память.

Итого, функция получает исходное изображение и параметры преобразования, выполняет преобразования, сохраняет полученный файл во временную папку и возвращает имя изображения. Теперь нам осталось только переложить файл в конечную папку.

Отвечу заранее на вопрос «Почему мы не можем сразу положить изменённый файл в конечную папку?». Можем. Однако не делаем для увеличения глубины абстракции, то есть, чтобы придать определённую универсальность функции. Вы же сможете её использовать на разных сайтах.

Совсем забыл. Добавляем в начало функции строку:

Она обозначает, что в функции будет использована глобальная переменная $tmp_path – путь к временной папке.

Вызов функции

Функцию нужно вызывать сразу после проверок. А также следует изменить ту часть скрипта, где мы копируем изображение в конечную папку. Вы ведь теперь работаем с новым изображением. Теперь схема загрузки такова: компьютер → временная папка сервера → наша временная папка → конечная папка. То есть, добавился ещё один промежуточный пункт.

Для пущего веселья добавим в нашу форму выпадающий список, чтобы мы устанавливать тип загрузки и поля для ввода градуса поворота.

В таком случае вызов функции будет такой:

Конечный результат

И наконец, конечный результат.

свойства изображения

Послесловие

Естественно, рассмотренный пример учебный. Однако он вполне рабочий. Что вы можете попробовать, забросив скрипт на сервер и создав папки для изображений и временных файлов. Скрипт можно бесконечно дорабатывать, изменять уровень абстракции, добавлять условия и параметры, преобразования, проверки, накладывать «водяной знак».

Идеальный вариант – осмыслить и допилить до своих требований.

Домашнее задание

Конечно, задание проверять никто не будет. Однако я рекомендую его выполнить для себя. Ведь программирование – это, прежде всего, практика. Итак:

Вынесите размеры эскиза ($max_thumb_size) и большого изображения ($max_size) из функции в настройки файла.

Попробуйте задавать их в параметрах функции. Это значительно повысит уровень абстракции.

Проработайте вариант, когда изображение ограничивается по большей стороне, а не только по ширине.

Попробуйте получить на выходе файл того же типа, что и исходный. То есть, например, если загружаете gif, то и уменьшенная копия будет gif.

Попробуйте генерировать и эскиз и большой файл за одну загрузку.

Попробуйте наложить «водяной знак».

Используя бонусный код, добавьте в функцию возможность создания квадратных файлов. Добавьте в форму выбор типа обрезки – квадратная или пропорциональная.

Удачи в разработках!

P.S. Если вы захотите генерировать не пропорциональное изображение, а вырезать серединку и делать квадратную картинку, вам поможет этот код. Вставить его в функцию resize вы должны сами. Уверен, что у вас получится.

До следующих встреч, уважаемые читатели

Если у вас есть вопросы, по загрузке изображений на сервер и изменению размеров изображений средствами языка PHP, то пишите в комменатриях к статье, я обязательно отвечу!

Автор: Алексей Опанасенко

Редакция: Рог Виктор и Андрей Бернацкий. Команда webformyself.

E-mail: contact@webformyself.com

Проект webformyself.com — Как создать свой сайт. Основы самостоятельного сайтостроения

«Киберсант-вебмастер» — самый полный курс по сайтостроению в рунете!

P.S. Хотите опубликовать интересный тематический материал и заработать? Если ответ «Да», то жмите сюда.

Бесплатный курс по PHP программированию

Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC

В курсе 39 уроков | 15 часов видео | исходники для каждого урока

Получить курс сейчас!

Разработка веб-приложения на PHP

Создайте веб-приложение на PHP на примере приема платежей на сайте

Смотреть

Метки: ,

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook:

Комментарии (83)

  1. Юрий Рузаев

    Отличная статья, как говорится вот именно этого мне и не хватало!!! Огромное спасибо ребята всем кто, кто создает такие прекрасные и познавательные темы, а в особенности Андрею Бернацкому и Рог Виктору!!! С уважением и пожеланием всего самого наилучшего, Юрий.

  2. Виктор

    Здравствуйте ребята !
    Я являюсь Вашим подписчиком, и есть одно недовольствие — это редко очень рассылаете рассылку.
    Ребята пишите больше писем для рассылки.

    И второе .
    У меня вопрос, Вы не собираетесь публиковать программы у себя на этом блоге.?
    Так как я программист, сайта нет, а охото чтобы мои программы хоть чуточку помогли кому нибудь.

    Спасибо. !

  3. Сергей

    Статья отличная, вообще в последнее время растет тенденция относительно интереса к теме web технологий, но а меня интересует проблема качественного составления ТЗ для рпботы над большими web проектами.

  4. Elena

    Виктор и Андрей!
    Вы настолько меня выручили, т.к. с этой проблемой я столкнулась именно сейчас.
    Попробую обязательно, и очень надеюсь, что получиться здорово!
    Большое вам спасибо- за актуальность и своевременность материала.
    Я не программист, но приходиться все делать самой и любая помощь,
    а тем более такая как Ваша-просто драгоценна.
    С уважением Елена СПб.

  5. Игорь

    Так вот как это делается на Одноклассниках и Вконтакте. Очень полезно. Но мне сейчас пока негде применить. А когда понадобится я этот сайт уже не найду.

  6. Татьяна

    Спасибо, очень нужная вещь, а главное — вовремя.

  7. Максим Мирный

    Ребята спасибо за ценный урок!
    Уже с нетерпением жду следующий.

  8. Данзан

    Спасибо, ребята! Очень нужные на мой взгляд материалы предоставляете! — Очень хотелось бы по скорее зарабатывать в Интернете.

  9. Sadr

    Молодцы ребята! Доброе дело делаете.
    Жаль. что это пока мне не по зубам. Уж больно я старый чайник. Да и подустал я за компом, уже 6-ой час утра. Вот так я пытаюсь освоить железку. Вам молодым — свежим мозгам, всё быстро даётся. Цените это. Ну а мы, деды ваши будем учиться у вас и обязательно научимся! Такое уж нынешнее время.

  10. Sergey

    Конечно хорошо бы было сделать это в видео уроке.
    Времени пока нет посмотреть и почитать, но обязательно прочту)))
    Спасибо за старания!!!!!!!

    • Never Lex

      Имхо, такой формат наиболее приемлем для разработчиков. Объясню почему. Вы в любой момент можете просмотреть по ходу статьи, что именно каждый кусок кода делает. Именно это нужно для осознания. А пересматривать видео несколько раз довольно затратно по времени и не интересно.

      Подобные уроки НЕ учат программированию в целом. Они показывают решение конкретной проблемы. Я ведь и сам учился по таким урокам и мне подобные статьи помогли намного больше видео материалов.

  11. Константин

    Да, статья действительно хорошая. Я обязательно воспользуюсь при необходимости. Но если чесно, то это не совсем то, что мне надо. Я делаю свой сайт на Joomla. У меня не получается сделать вставку и показ презентаций Power Point на страницы материалов. Для этого нужен соответствующий модуль для Joomla. И вот где его взять пока не знаю. Поэтому хотелось бы узнать именно по этой теме, «Как написать самому модуль Joomla для вставки и вещания презентаций Power Point», или где взять готовый. Буду рад помощи.

  12. Владимир

    Однозначно полезная статья, от себя добавлю.

    Ещё можно сгенерировать уникальное имя для загружаемого файла чтобы было удобнее с ним работать в будущем, например так:

    $uid = array_merge( range(‘a’, ‘z’), range(’0′, ’9′));
    $_SESSION['uid'] = »;

    Ну и потом естественно задать новое имя загруженному файлу:
    rename ($Dir.$_FILES['uploadfile']['name'], $Dir.$_SESSION['uid'].’.jpg’);

  13. Сергий

    Мужики, как Вы оцениваете Радикал-фотоклиент?

  14. Iskander

    Урок то что надо! Только было бы лучше увидеть это в стиле видео Андрея Бернацкого.
    А так thanx ребята!

  15. Николай

    Спасибо!
    Очень полезный урок!
    Воспользуюсь.
    Удачи Вам!

  16. Николай

    Парни здравствуйте!!! Мног всяких книг и курсов просмотрел , но конкретно ничего не нашел и по сайтостроению и их обработке. Ваш курс мне понравился. Буду рад если мои ожидания сбудутся. Очень нужное дело для нас «чайников» делаете. СПАСИБО!!! С уважением Николай Пахомов 68 лет.

  17. Елена

    Обалденная статья! Начинаешь верить, что все эти закорючки могут быть кому-то интересны. Даже пожалела, что нельзя объять необъятное — времени на то, чтобы вникнуть в эти тонкости катастрофически не хватает. Но обязательно сохраню, ведь жизнь полна неожиданностей. Как знать, может и этим предстоит заняться:)

  18. Михаил

    Картинки можно же конечно и с помощью фотошопа уникализировать, но скрипт интересный. Можно поковыряться на предмет автоматического сграбливания и публикации на сайт. Спасибо.

  19. Юрий

    СПАСИБО ребята! Но, для меня это пока еще сложно! Я еще, к сожалению, ЭЛЕКТРОЧАЙНИК.
    С искренним УВАЖЕНИЕМ! Юрий.

  20. Рамис

    Спасибо за очень полезный урок!

  21. Лаура

    Ребята, вы молодцы вообще… все четко и ясно, яснее не куда… Я увлеклась сайтостроенией и много нашла для себя полезного, буду следить за россылкой и жду интересных предложений. Удачи!

  22. Максим

    Классный урок! Я хотя еще довольно зеленый в сайтостроении, но вижу, что из него можно почерпнуть очень много полезной информации. Обязательно воспользуюсь при необходимости! Большое спасибо авторам, за отличную тему!

  23. Александр

    Спасибо! обязательно воспользуюсь,сейчас перевожу свой сайт на PHP и этот урок как нельзя кстати. Может вы подскажете, чем движок на СMS отличается от WordPress и что лучше.

  24. Юлия

    Ребята, спасибо большое! Сколько трудозатрат — я представляю. Только почему поменяли стиль? Если я правильно поняла, то это второй урок? Первый был А.Бернацкого на видео, так легко и доступно воспринимается!!!!!
    Огромное пожелание: можно на видео и с возможностью скачивания на компьютер с обычным расширением? Пожалуйста!!!!

  25. Владимир

    Огромное спасибо!Успехов и Всех благ!

  26. Lena

    Спасибо! Сейчас попробуем))

  27. phz

    А нечего что загрузка файлов используется функция move-uploaded-file, а не copy как у вас в скрипте.

    Читайте про http://php.net/manual/en/function.move-uploaded-file.php

    Что это за шаравары вечислава использ. copy для загрузки файлов…

  28. Василий Мирчук

    Немного похоже на кибер грамоту. Но вникаешь, делаешь и получается. Спасибо!
    Приду еще.

  29. Фируз

    Мне нравятся Ваши уроки молодцы! Спасибо Вам за эти уроки. Я такого типа другой Ваш урок взял и сейчас тоже разбираю, по HTML языку. Спасибо ещё раз!!! Побольше бы таких проектов было бы в рунете, тогда можно было бы многое самому сделать и научиться сделать. Одним словом. МОЛОДЦЫ РЕБЯТА!!!

  30. Алексей

    Спасибо большое за урок, мне как раз это понадобилось прямо сейчас!
    У меня только вопрос, можно ли как-то сделать чтобы на выходе файл всегда имел расширение jpg независимо от исходного расширения картинки?

  31. Света

    Ошибка в «Проверки»
    Пришлось время потратить, чтобы понять в чем дело.
    Дальше в «Конечный результат» ошибки нет

  32. Евгений

    Как раз то, что искал. Попробую прикрутить к своей форме для загрузки фоток.
    Спасибо.

  33. Евгений

    Что-то не так. IE-8 пропускает только .gif файлы.

  34. chelovek

    Спасибо, автор! Уважил чайника…

  35. chelovek

    Здравствуйте.
    У меня такой вопрос. Вы пишите:
    «Далее создаём изображение для дальнейших преобразований:
    1.if ($file['type'] == ‘image/jpeg’)
    2. $source = imagecreatefromjpeg ($file['tmp_name']);
    3.elseif ($file['type'] == ‘image/png’)
    4. $source = imagecreatefrompng ($file['tmp_name']);
    5.elseif ($file['type'] == ‘image/gif’)
    6. $source = imagecreatefromgif ($file['tmp_name']);
    7.else
    8. return false; »

    То есть изображение будет создано выборочно только из трёх типов — image/jpeg, image/png, image/gif.
    Но в Internet Explorer формат jpg может иметь тип mage/pjpeg, а png иметь тип image/x-png и тогда функция возвратит значение «ложь». Как это можно учесть? Спасибо.

    • Андрей Кудлай

      Немного дописать функцию самостоятельно — специально для IE добавить в разрешенные типы еще и MIME-тип ‘image/pjpeg’ (это для расширений jpg под IE), ну и для других типов, соответственно, тоже. Еще один вариант — пользоваться другими браузерами раз у IE своя собственная таблица MIME-типов))
      Кстати, может кому-то пригодится — вот общепринятая таблица MIME-типов — http://www.spravkaweb.ru/php/pril/mime
      P.S. Спасибо за вопрос :) а то пишу урок, где используется в частности загрузка файлов на сервер и по причине того, что IE как бы и не пользуюсь, — совсем про него забыл.

      • chelovek

        Это вам большое спасибо за очень последовательные, понятные уроки. Для новичков это очень важно ))
        Для Internet Explorer, думаю, мог бы пойти и такой код:

        if (ereg(«jpeg», $file['type'])) {$source = imagecreatefromjpeg($file['tmp_name']);}
        elseif (ereg(«gif», $file['type'])) {$source = imagecreatefromgif($file['tmp_name']);}
        elseif (ereg(«png», $file['type'])) {$source = imagecreatefrompng($file['tmp_name']);}
        else return false;

        Ещё раз большое спасибо. Удачи! )

  36. Артём

    На большинстве фотографий пишет — запрещенный тип файла, хотя формат у них JPG.
    Отчего так ?

    • Андрей Кудлай

      Рискну предположить, что Вы используете браузер Internet Explorer. Если я прав, то в комментариях выше Вы найдете ответ на Ваш вопрос.

      • Артём

        Нет. Я использую все браузеры. Единственное отличие что я заметил, было — сжатие бит на пиксель 5. В тех файлах, что работали оно было не более трёх.

        • Андрей Кудлай

          Тогда нужно смотреть сами файлы картинок, которые не получается загрузить. Если хотите, можете выложить 1-2 таких файла — я посмотрю.

          • Артём

            Гм… Оказывается эта проблема существует только на денвере. На хостинге всё залетало. Спасибо.

          • Андрей Кудлай

            Пожалуйста :)

  37. Артём

    А как сделать так, чтобы выводило одновременно и большое изображение и эскиз ?

    • Андрей Кудлай

      Для этого придется вносить существенные правки в код, например:
      1) предусмотреть генерацию имени для второй картинки;
      2) убрать проверку на тип и просто обрезать дважды картинку согласно разной ширине.
      3) ну и, собственно, организовать копирование и вывод не одного, а двух изображений.

      • Артем

        А что лучше в плане уменьшения нагрузки, ресайзить имидж два раза, или воспользоваться скриптом для создания миниатюр налету ? С учетом того, что этот самый скрипт использует кеширование.

  38. Вика

    А нет статьи по загрузке файлов для пользователей на WordPress программно?

  39. melomaniac

    Здраствуйте, не зря искал, нашел, спс вам за скриптик :)
    Если подскажите еще как сделать чтоб имя конечного файла, писалось в бд, или просто чтоб автоматом вставлялось в textarea к примеру, а потом по событию писалось в бд ?

    • Андрей Кудлай

      Чтобы записать имя картинки в БД достаточно использовать это имя (переменную $name) в запросе на добавление в БД — INSERT. Сделать это можно, например, сразу после копирования файла и вывода сообщения «Загрузка прошла удачно».

      • melomaniac

        Спс, с етим разобрался, подскажите пожалуйста еще две вещи: как сделать несколько форм, в идеале выбираем несколько файлов, а потом грузим все сразу на серв, и насколько я понял можно выставлять только ширину, а что изменить для того чтобы можно было задавать и высоту в px ?

        • Андрей Кудлай

          За получение высоты отвечает функция imagesy(). Результат ее работы сохранен в коде в переменную $h_src. Соответственно, можете работать с этой переменной, вместо (или вместе с) $w_src, где сохранена ширина картинки.
          Для загрузки нескольких файлов просто добавьте соответствующее количество полей типа file в форму. Дайте этим полям разные имена или массив имен, например так:
          <input type=file name=picture[]>
          <input type=file name=picture[]>

  40. melomaniac

    Добрый вечер, с заданием размеров разобрался, не знаю насколько правильно, но задал фикс, а вот с несколькими формами никак если так:

    , запрещенный тип файла, если

    , то грузит только вторую картинку :(
    Я в php новичек, буду благодарен если поможете разобратся :(

    • Андрей Кудлай

      «Если так» и «если» осталось пустым :)
      Все потому, что комментарии не предназначены для решения подобных вопросов. Создайте тему на нашем форуме и Вам обязательно помогут.

  41. Алексей

    Доброго времени суток, у меня такой вопрос, прикрутил данный скрипт к своему сайту, но почему-то картинка не загружается в указанную папку(папка пуста), но адрес пишется в базу, и везде прописывается как положено.
    После добавления тоже пишет что загрузка прошла успешно.
    Не подскажете что может быть, куда смотреть?

  42. Светлый

    Спасибо за замечательный урок. Хорошее описание позволило доработать под свои нужды. Мой вариант содержит 3 директории и отсутствует выбор размера в форме. Дирректории 1я временная, 2я содержит квадратные мелкие превьюшки и 3я с уменьшеными до 800 пропорциональными оригиналами.

  43. bairon

    А как сделать что бы сохранялись два изображения, в разные папки?
    Заранее спасибо!

    • Андрей Кудлай

      Вызвать функцию, сохраняющую картинку, дважды, указывая каждый раз разные папки для сохранения. Если не ошибаюсь, в уроке это функция copy.

  44. Ден Абашин

    И всётаки как сделать ограничение по высоте?

  45. Александр

    Здравствуйте.

    подскажите как добавить эту форму http://webformyself.com/kak-sdelat-formu-zagruzki-fajla-na-sajte/ к этому коду , что бы изменялось название файла при загрузке на указанное в поле. «название файла»

  46. Марат

    После слов «путь к папке временных файлов» — идет код, там ошибка в 26 строчке, перед переменной «$path» отсутствует одинарная кавычка и точка.
    Но в любом случае спасибо!

  47. Айк

    А как оптимизировать 40.000 изображений которые на сайте уже,кто знает хороший плагин?

    21 век на дворе,нужно автоматизировать процесс сжатия,а не оптимизировать каждое изображение по отдельности.
    Загрузил на сайт-плагин оптимизировал и все -автоматизировать,не все нужно руками делать,цените время друзья !

  48. Muhammadali

    большое спасибо за этот урок, это было очень полезно для меня

  49. Кирилл

    Есть готовая реализация для тех, кто использует Ларавел. Пакет называется UploadImage. Есть статья на русском: cleverman.org/post/37