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

How To Upload An Image With PHP

In this quick tutorial we set up a basic HTML form to upload images with PHP, we also explore how to secure our PHP script so it can’t be abused by malicious users.

Setting Up An Image Upload Form

We start with a basic form.

The form contains a submit button and has an action attribute. The action attribute points to the page the form will post all its contents to when the submit button is clicked.

form action="upload.php" method="POST"> button type="submit">Uploadbutton> form>

The form posts to a PHP file called upload.php . This file will handle the image upload. We’ll get to that in a minute.

To allow users to select a file we add a file input field.

form action="upload.php" method="POST" enctype="multipart/form-data"> input type="file" name="image" accept="image/*" /> button type="submit">Uploadbutton> form>

At the same time we’ve also added the enctype form attribute and set it to «multipart/form-data» . This is needed if we have a file input field in our form.

Because we’re only uploading images we add the accept attribute to the file input element and set it to image/* telling it to only accept files that have a mimetype that starts with image , like image/jpeg or image/png .

Let’s write the PHP image upload handler next.

Handling the PHP Image Upload

We’ll create a new file called upload.php in the same directory as the page that contains our form.

Next we create a directory called «images» , also in the same directory. This is where our script will store uploaded image files using the move_uploaded_file function.

 // Get reference to uploaded image $image_file = $_FILES["image"]; // Image not defined, let's exit if (!isset($image_file))  die('No file uploaded.'); > // Move the temp image file to the images/ directory move_uploaded_file( // Temp image location $image_file["tmp_name"], // New image location, __DIR__ is the location of the current PHP file __DIR__ . "/images/" . $image_file["name"] );

We’re done. This is all that’s needed to make it work.

Unfortunately not everyone on the internet is a saint. Our script currently allows anyone to upload anything, this is a security risk. We need to make sure people upload valid images and are not trying to harm our server.

Securing The Image Upload Process

We’re going to make extra sure these three things are in order.

  • The file needs to be an image.
  • The file must be smaller than 5MB.
  • The file must have a valid name.

Making Sure The File Is An Image

Let’s start by making sure the uploaded file is indeed an image.

Using exif_imagetype we can get the image mimetype, the function returns false when the file is not an image.

 // Get reference to uploaded image $image_file = $_FILES["image"]; // Exit if no file uploaded if (!isset($image_file))  die('No file uploaded.'); > // Exit if is not a valid image file $image_type = exif_imagetype($image_file["tmp_name"]); if (!$image_type)  die('Uploaded file is not an image.'); > // Move the temp image file to the images/ directory move_uploaded_file( // Temp image location $image_file["tmp_name"], // New image location __DIR__ . "/images/" . $image_file["name"] );

Next we need to stop users from uploading very large files.

Limiting The File Size

In the example below we limit the image file size to 5MB, of course you can choose your own limit, but it’s a good idea to at least cap it at a certain point to prevent users from uploading gigabytes of data in an attempt to DoS attack your server.

In the directory of our upload.php script we create a .htaccess file and set its contents to the following.

The LimitRequestBody prevents a request from exceeding 5MB, note that this includes other fields in the form.

Now let’s make sure users can’t uploading 0 byte files. We use filesize to read out the actual file size instead of rely on the [«size»] reported by $_FILES as that can be modified by the user.

 // Get reference to uploaded image $image_file = $_FILES["image"]; // Exit if no file uploaded if (!isset($image_file))  die('No file uploaded.'); > // Exit if image file is zero bytes if (filesize($image_file["tmp_name"])  0)  die('Uploaded file has no contents.'); > // Exit if is not a valid image file $image_type = exif_imagetype($image_file["tmp_name"]); if (!$image_type)  die('Uploaded file is not an image.'); > // Move the temp image file to the images/ directory move_uploaded_file( // Temp image location $image_file["tmp_name"], // New image location __DIR__ . "/images/" . $image_file["name"] );

Let’s now make sure the file name of the image is valid.

Guarding Against Malicious File Names

Malicious actors can try to upload an image with named ‘../index.php’ , our PHP script would now store this “image” in ‘images/../index.php’ possibly overwriting our own index.php file.

We can try to sanitize the image file name, but a safer approach is to generate our own file name.

We’ll generate some random_bytes and use those as the name for our image.

 // Get reference to uploaded image $image_file = $_FILES["image"]; // Exit if no file uploaded if (!isset($image_file))  die('No file uploaded.'); > // Exit if image file is zero bytes if (filesize($image_file["tmp_name"])  0)  die('Uploaded file has no contents.'); > // Exit if is not a valid image file $image_type = exif_imagetype($image_file["tmp_name"]); if (!$image_type)  die('Uploaded file is not an image.'); > // Get file extension based on file type, to prepend a dot we pass true as the second parameter $image_extension = image_type_to_extension($image_type, true); // Create a unique image name $image_name = bin2hex(random_bytes(16)) . $image_extension; // Move the temp image file to the images directory move_uploaded_file( // Temp image location $image_file["tmp_name"], // New image location __DIR__ . "/images/" . $image_name );

Our last step is to prevent code from being executed in our images directory.

Preventing Code Execution In The Images Directory

In our images directory we create a .htaccess file and set its contents to the following to prevent any uploaded PHP files from being run.

This make sure that PHP code in this folder won’t execute. So if someone still manages to upload a PHP file, for example a PHP file disguised as an image, it still won’t run.

Our file upload process is now secure. 🎉

Conclusion

We’ve written a basic form with file input element, to handle the upload we created a PHP file that moves the uploaded image to a directory on the server. To secure the upload process, we made sure the filename is valid, the file size is not too high, and the uploaded file is actually an image.

If you’re also looking to add image editing functionality to the file upload field you can use the element. This Pintura powered web component automatically opens a powerful image editor when an image is added to the field and enables your users to edit images before upload.

I share web dev tips on Twitter, if you found this interesting and want to learn more, follow me there

At PQINA I design and build highly polished web components.

Make sure to check out FilePond a free file upload component, and Pintura an image editor that works on every device.

Источник

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

Итак, мы продолжаем обсуждать тему загрузки файлов на сервер. Если вы ещё не читали статью «Что необходимо учитывать при загрузке файлов на сервер», то рекомендую начать именно с неё.

В вышеуказанной статье мы обсудили общие нюансы загрузки файлов на сервер. А теперь пришло время программировать! В данном примере мы реализуем:

  1. Корректную загрузку картинки на сервер.
  2. Проверку, выбран файл или нет.
  3. Проверку на размер файла.
  4. Грамотную проверку расширения файла.

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

Для начала определим, какие файлы и папки будут в нашем проекте:

  1. index.php – обработчик отправки формы
  2. functions.php – библиотека с двумя функциями
  3. img – папка, в которую будут загружаться изображения

Посмотрим на содержимое индекса.

         Файл успешно загружен!"; > else< // выводим сообщение об ошибке echo "$check"; > > ?>  

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

Главное — просто понять схему работы данного скрипта. У нас есть две функции:

  1. can_upload – производит все проверки: возвращает true либо строку с сообщением об ошибке
  2. make_upload – производит загрузку файла на сервер

Соответственно, если форма была отправлена, мы сначала вызываем функцию can_upload. Если она подтвердила, что файл подходит нам по всем параметрам, то мы вызываем функцию make_upload. Иначе просто распечатываем сообщение об ошибке.

Здесь всё достаточно коротко и логично. Схема стандартная. Поэтому нас больше интересует, а что именно делают эти загадочные функции can_upload и make_upload!

Загрузка изображений — фукнции.

Рассмотрим файл functions.php

Сначала всего пару слов про функцию make_upload, поскольку она проще. Обратите внимание на то, что мы перед именем файла вставляем mt_rand(0, 10000), т.е, случайное число от 0 до 10000. Делается это для того, чтобы у файла было уникальное имя. В противном случае, при загрузке двух картинок с одинаковыми именами, вторая заменит первую.

Кстати, если вы задались резонным вопросом, а где же закрывающий тег php в данном файле, значит, вы явно не читали статью «Ошибка headers already sent»!

Необходимые проверки

Основной же интерес для нас представляет функция can_upload.

($file[‘name’] == ») — мелочь, знакомая вам по предыдущей статье.

А вот ($file[‘size’] == 0) — это забавно! Особенно с учётом того, что мы говорим при этом, что файл слишком большой! Разгадка кроется в том, что если файл был больше, чем разрешено в настройках сервера, то он не будет загружен вообще. А если файл не загружен, то вполне логично, что его размер равен нулю.

Ну и наконец, проверка расширения. Здесь мы используем так называемую технику белого листа. Таким листом у нас является массив $types, в котором мы перечисляем все допустимые расширения. Если расширение загружаемого файла не найдено в массиве, значит нам загружают что-то не то.

Вот собственно говоря и всё! Скрипт надёжный, аккуратный и лаконичный.

А в следующей статье мы поговорим о том, как можно наложить на загружаемую картинку водяной знак. Рекомендую прочесть!

Понравился материал? Поделись с друзьями!

Источник

Читайте также:  Определитель матрицы рекурсивно python
Оцените статью