Поради для всіх
» » PHP: завантаження файла на сервер

PHP: завантаження файла на сервер

Додано: 09.08.16
Автор: admin
Завантаження файлів через PHP - вельми цікаве справа, до якої треба підходити дуже уважно. В інтернеті можна знайти безліч прикладів реалізації завантаження файлів, але не всі вони гарні і відповідають правилами безпеки. Такі речі треба доводити до кінця, навіть якщо на це піде багато часу. Якщо ви залишите пролом в коді, то весь ваш сервер може опинитися під загрозою.

Безпека

За допомогою PHP завантаження файлів на сервер здійснюється досить легко. Код дуже короткий і простий. Всього лише пара рядків. Але такий метод небезпечний. Куди більше часу і рядків коду йде на безпеку.


Небезпека полягає в тому, що, якщо не робити перевірок, будь зловмисник зможе завантажити свої скрипти на ваш сервер. При цьому у нього буде повний доступ. Він зможе зробити все, що захоче:
  • видалити бази;
  • видалити файли сайтів;
  • змінити файли сайтів;
  • додати свою рекламу на ваш сайт;
  • завантажити віруси;
  • перенаправляти всіх користувачів на свої сайти;
  • і багато іншого, що прийде в голову зломщикові.
  • Завжди потрібно перевіряти, що файл намагається завантажити користувач. Якщо, наприклад, ви завантажуєте тільки фотографії, необхідно перевірити, що цей файл точно є зображенням. В іншому випадку вам завантажать що завгодно. Як саме реалізувати перевірку, буде показано далі, при безпосередньому розгляді скрипта завантаження файлів.

    Створення форми PHP

    Форма завантаження файлу виглядає дуже просто. Вистачає кнопки огляду і кнопки завантаження.
    PHP: завантаження файла на сервер
    Описувати створення форми не будемо, так як це легко. Подальші інструкції передбачають, що у вас вже є базові поняття HTML (інакше б ви не шукали інформацію про завантаження на PHP). Але зверніть увагу, що для передачі даних в формі потрібно додати атрибут enctype.
    PHP: завантаження файла на сервер
    Інакше дані про файл обробникові передаватися не будуть.

    Як це повинно працювати?

    PHP: завантаження файла на сервер
    При натисканні на кнопку огляду у вас повинно відкритися вікно, де запропонують вибрати файл. Після цього повинен буде з'явитися шлях, де розташований файл.
    PHP: завантаження файла на сервер
    Якщо шлях не з'явиться, то виконайте цю дію ще раз. Після натискання на кнопку завантаження файлом-обробником можна видати будь-яку інформацію.
    PHP: завантаження файла на сервер
    Наприклад, можна написати рядок, в якій зазначено, що файл з таким-то" назвою був успішно завантажено "таку-то" папку. Зрозуміло, ім'я файлу буде видаватися завжди різне. Зазвичай таку детальну інформацію використовують для налагодження коду. Таким чином можна перевірити, що дані передаються та запис відбувається в потрібну вам папку. Тобто навіть ім'я файлу не вказують. Оскільки це зайва інформація, яка користувачеві не потрібна.


    Має сенс висновок даних про ім'я тільки в тому випадку, якщо користувач завантажує кілька файлів. Такий випадок розглянемо трохи далі. Не будемо забігати вперед.

    Налаштування

    В PHP завантаження файлу на сервер вимагає певних параметрів, які потрібно робити в файлі php.ini. У цьому файлі дуже багато налаштувань. Вони всі нам не потрібні. Нас цікавлять три рядки: file_uploads, upload_tmp_dir і upload_max_filesize. Зверніть увагу на те, що ці налаштування торкнуться всіх ваших сайтів на сервері, а не тільки якогось одного. Тому ставте максимальний розмір виходячи з того, що у вас будуть завантажувати користувачі. Не рекомендується задавати занадто великі значення.
    Після того, як ви змінили значення в цих параметрах, сервер потрібно перезавантажувати. Інакше налаштування не вступлять в силу, так як вони зчитуються в момент завантаження сервера. Зробити це можна в консолі, підключившись через SSH до сервера. Достатньо ввести команду service httpd restart, і після цього параметри вступлять в силу. Інший спосіб - перезапуск через ISP-панель або через біллінг-панель провайдера.
    PHP: завантаження файла на сервер

    Масив з файлом

    В PHP завантаження файлу відбувається за допомогою масиву $_FILES. У ньому міститься вся інформація про файли, які ми будемо завантажувати. Для того щоб показати, яка саме інформація міститься в цьому масиві, достатньо написати в файлі-оброблювачі наступне.
    PHP: завантаження файла на сервер
    Виберіть будь-який файл і натисніть кнопку "Завантажити". На сторінці обробника виведеться інформація, яка зберігається в $_FILES. Змінна пишеться повністю з великими літерами. PHP - мова регистрозависимий.
    PHP: завантаження файла на сервер
    Як бачите, в цьому масиві є багато полів. Всі вони для нас важливі. У першому полі зберігається назва файлу в тому вигляді, в якому воно використовується на вашому комп'ютері. У графі type вказаний тип файлу. Поля tmp_name відповідає ім'я тимчасового файлу. Після закінчення роботи скрипта він буде видалено. У полі error зберігається код помилки. Про це трохи далі. Size - розмір в байтах.

    Помилки

    Здійснювана через PHP завантаження файлу завжди супроводжується кодом помилки. Повідомлення про помилку укладено в полі "error". На скріншоті помилка дорівнює нулю.
    PHP: завантаження файла на сервер
    Розглянемо значення всіх помилок:
    PHP: завантаження файла на сервер
    Вище було сказано про параметр, який можна вказати в звичайному HTML. Ось приклад форми для завантаження файлу, де зазначене обмеження в розмірі завантажуваного файлу.
    PHP: завантаження файла на сервер

    PHP: скрипт завантаження файлу

    Як же все відбувається на практиці? В PHP завантаження файлу відбувається командою copy. Якщо вас цікавило питання про те, як завантажити файл, то відповіддю буде просто copy, в якій використовується два параметра - вихідний файл та файл призначення.
    Але, як писалося вище, обмежуватися цим не можна в цілях безпеки. Наприклад, перевірити що за файл ми вантажимо, можна за допомогою поля type в масиві $_FILES. Спочатку розберемося з перевіркою, а потім перейдемо до повноцінного скрипту Припустимо, ви хочете, щоб користувачі могли завантажити фотографію з дозволом тільки GIF, JPEG або PNG. Вказати це можна ось так. if($_FILES['file_upload'] ['type']!= "image/gif") {
    echo "Вибачте, ми підтримуємо завантаження Gif-файлів";
    exit;
    } Якщо хочете вантажити всі 3 типу, то просто додайте додаткову умову з іншим типом зображення. Копіювання робиться ось так: copy(файл 1 файл 2). У нашому випадку, коли робота йде з завантаженням з комп'ютера на сервер, можна робити так copy($_FILES['file_upload'] ["tmp_name"], "1.jpg") Тобто файл буде копіюватися з назвою 1.jpg. Це не зовсім правильно. В даному випадку це тільки приклад. Ім'я файлу завжди потрібно ставити різне, і розширення вказувати в залежності від файлу. Визначити розширення можна різними способами. Все залежить від ерудиції розробника. Один з найшвидших способів (різниця в десятих частках секундах) визначення розширення - це наступний код. $path_info = pathinfo($_FILES['photo1'] ["name"]); $ext=$path_info['extension']; У змінній $ext у нас буде зберігатися шукане розширення. А ім'я файлу можна задати випадковим чином за допомогою md5. Якщо ви плануєте завантажувати багато файлів, то краще вантажити їх в різні папки. Так буде зручніше. Особливо якщо захочете провести чистку. Код для завантаження буде наступним.
    PHP: завантаження файла на сервер
    ///наявність фото if ($_FILES['photo1'] ['tmp_name']== null) { echo (" Файл не вказаний. Тому "); exit; } ///. Припустимо, у вас для якого-небудь проекту на сервері дозволено завантажувати великі файли (відео), але тут будуть тільки фотографії, і користувачів потрібно обмежити if (($_FILES["photo1"] ["size"]> 1024*1024*2) { ?> Максимально дозволений розмір зображення 2 Мб Тому <? exit; } //створення папок //створення папки поточного місяця if (!file_exists("img/".date("M"))) { mkdir("img/".date("M")); } //створення папки поточного дня if (!file_exists("img/".date("M")."/".date("d"))) { mkdir("img/".date("M")."/".date("d")); } ///розширення файлу $path_info = pathinfo($_FILES['photo1'] ["name"]); $ext=$path_info['extension']; ///генеруємо ім'я файлу $id=md5(date("Y-M-d")); if(copy($_FILES['photo1'] ["tmp_name"], "img/".date("M")."/".date("d")."/".$id.$ext)) { echo ("файл успішно завантажений"); } ///будь-які подальші дії (запис в базу тощо) }

    Кілька файлів

    Завантаження декількох файлів (PHP) відбувається за допомогою додаткових полів у формі.
    PHP: завантаження файла на сервер
    Даний спосіб не дуже хороший, так як обмежує кількість файлів для завантаження. Більш того, вважається поганим тоном в програмуванні. Намагайтеся робити все динамічний. Ідеальний варіант - це можливість вибору відразу великої кількості файлів натисканням на одну кнопку. Для цього створюємо форму ось таким кодом.



    Зверніть увагу, що додано слово multiple, і ім'я задано масив[]. У цьому випадку масив $_FILES буде трохи відрізнятися. У вас вийде масив в масиві. Для перевірки можете знову скористатися var_dump($_FILES); Всі ваші файли будуть розташовуватися в масиві ось так:
  • $_FILES["file1"] ["name"] [0]
  • $_FILES["file1"] ["name"] [1]
  • І так далі.
  • У дужках вказується номер файлу в масиві. Відлік з нуля. Обробляємо їх точно так само, просто задаємо цикл і при зверненні в вище описаному коді в кінці додаємо індекс[$i]. $i=0; while ($_FILES["file1"] ["name"] [$i]<> ") { ///вставляємо вищеописаний код } Таким чином, у вас буде відбуватися через PHP завантаження файлів на сервер в одному циклі без зайвого повторення коду, як це зазвичай буває, якщо використовувати варіант зі статичним кількістю файлів (останнє фото).