Як завантажувати файли на сервер Надсилання файлів на сервер. Тепер про те, як це реалізувати практично

Останнє оновлення: 1.11.2015

Щоб завантажити файл на сервер, нам потрібно використовувати форму з параметром enctype="multipart/form-data" та масив $_FILES . Отже, створимо файл upload.phpз наступним вмістом:

завантаження файлу

Виберіть файл:



Тут визначено форми з атрибутом enctype="multipart/form-data" . Форма містить спеціальне поле для вибору файлу.

Всі файли, що завантажуються, потрапляють в асоціативний масив $_FILES. Щоб визначити, чи є взагалі завантажені файли, можна використовувати конструкцію if: if ($_FILES)

Масив $_FILES є двовимірним. Ми можемо завантажити набір файлів, і кожен завантажений файл можна отримати за ключом, який збігається з атрибутом name .

Оскільки елемент для завантаження файлу на формі має name="filename" , цей файл ми можемо отримати за допомогою виразу $_FILES["filename"] .

Кожен об'єкт файлу має свої параметри, які ми можемо отримати:

    $_FILES["file"]["name"] : ім'я файлу

    $_FILES["file"]["type"] : тип вмісту файлу, наприклад image/jpeg

    $_FILES["file"]["size"] : розмір файлу в байтах

    $_FILES["file"]["tmp_name"] : ім'я тимчасового файлу, збереженого на сервері

    $_FILES["file"]["error"] : код помилки під час завантаження

Також ми можемо перевірити наявність помилок під час завантаження. Якщо у нас немає помилки, поле $_FILES["filename"]["error"] містить значення UPLOAD_ERR_OK .

При надсиланні файлу на сервер він спочатку завантажується в тимчасове місце, з якого потім за допомогою функції move_uploaded_file() він переміщається до каталогу сервера.

Функція move_uploaded_file() приймає два параметри шлях до завантаженого тимчасового файлу та шлях, куди треба помістити завантажений файл.

Обмеження та налаштування завантаження

За замовчуванням розмір файлів, що завантажуються, обмежений 2 мб. Однак, можна налаштувати цей показник у файлі конфігурації. Змінимо цей показник, наприклад, до 10 мегабайт. Для цього знайдемо у файлі php.iniнаступний рядок:

Upload_max_filesize = 2M

Змінимо її на

Upload_max_filesize = 10M

Також ми можемо налаштувати папку для тимчасових файлів, що завантажуються. Для цього у файлі php.iniзнайдемо наступний рядок:

;upload_tmp_dir =

Змінимо її на

Upload_tmp_dir = "C:/php/upload"

Також у каталозі php нам треба створити папку upload.

Мультизавантаження

Змінимо скрипт upload.phpтак, щоб він підтримував множинне завантаження:

$error) ( if ($error == UPLOAD_ERR_OK) ( $tmp_name = $_FILES["uploads"]["tmp_name"][$key]; $name = $_FILES["uploads"]["name"][$ key]; move_uploaded_file($tmp_name, "$name");) )>

завантаження файлу






Кожне поле вибору файлу має атрибут name="uploads" , тому сервер розглядатиме набір відправлених файлів як єдиний масив.

Потім використовуючи цикл foreach, проходимо по всіх файлах і зберігаємо їх у каталог веб-сайту.

Якщо Вам потрібно було віддавати файли не безпосередньо веб-сервером, а за допомогою PHP (наприклад для збору статистики завантажень), прошу під кат.

1. Використовуємо readfile()

Метод хороший тим, що працює з коробки. Потрібно лише написати свою функцію відправки файлу (трохи змінений приклад із офіційної документації):

Function file_force_download($file) ( if (file_exists($file)) ( // скидаємо буфер виведення PHP, щоб уникнути переповнення пам'яті виділеної під скрипт // якщо цього не зробити файл буде читатися в пам'ять повністю! if (ob_get_level()) ( ob_end_clean(); ) // змушуємо браузер показати вікно збереження файлу header("Content-Description: File Transfer"); header("Content-Type: application/octet-stream"); =" . basename($file)); header("Content-Transfer-Encoding: binary"); header("Expires: 0"); public"); header("Content-Length: " . filesize($file)); // читаємо файл і відправляємо його користувачу readfile($file); exit; ) )
У такий спосіб можна відправляти навіть великі файли, оскільки PHP читатиме файл і відразу віддаватиме його користувачу частинами. У документації чітко сказано, що readfile() не повиненстворювати проблеми із пам'яттю.

особливості:

  • Файл читається у внутрішній буфер функції readfile(), розмір якого становить 8кБ (спасибі 2fast4rabbit)

2. Читаємо та відправляємо файл вручну

Метод використовує той же Drupal при надсиланні файлів із приватної файлової системи (файли недоступні безпосередньо за посиланнями):

Function file_force_download($file) ( if (file_exists($file)) ( // скидаємо буфер виведення PHP, щоб уникнути переповнення пам'яті виділеної під скрипт // якщо цього не зробити файл буде читатися в пам'ять повністю! if (ob_get_level()) ( ob_end_clean(); ) // змушуємо браузер показати вікно збереження файлу header("Content-Description: File Transfer"); header("Content-Type: application/octet-stream"); =" . basename($file)); header("Content-Transfer-Encoding: binary"); header("Expires: 0"); public"); header("Content-Length: " . filesize($file)); // читаємо файл і відправляємо його користувачу if ($fd = fopen($file, "rb")) ( while (!feof($ fd)) ( print fread($fd, 1024); ) fclose($fd); ) exit;
особливості:

  • Скрипт чекає доки весь файл буде прочитаний і відданий користувачеві.
  • Дозволяє заощадити пам'ять сервера

3. Використовуємо модуль веб-сервера

3a. Apache
Модуль XSendFile дозволяє за допомогою спеціального заголовка передати надсилання файлу самому Apache. Існують версії Unix і Windows, під версії 2.0.*, 2.2.* і 2.4.*

У налаштуваннях хоста потрібно увімкнути перехоплення заголовка за допомогою директиви:
XSendFile On
Також можна вказати білий список директорій, файли яких можуть бути оброблені. Важливо: якщо у вас сервер на базі Windows шлях повинен включати букву диска у верхньому регістрі.

Опис можливих опцій на сайті розробника: https://tn123.org/mod_xsendfile/

Приклад відправлення файлу:

Function file_force_download($file) ( if (file_exists($file)) ( header("X-SendFile: " . realpath($file)); header("Content-Type: application/octet-stream"); ​​header(" Content-Disposition: attachment; filename=" . basename($file)); exit; ) )

3b. Nginx
Nginx вміє відправляти файли із коробки через спеціальний заголовок.

Для коректної роботи потрібно заборонити доступ до папки безпосередньо через файл конфігурації:
location /protected/ ( internal; root /some/path; )
Приклад відправлення файлу (файл повинен бути у директорії /some/path/protected):

Function file_force_download($file) ( if (file_exists($file)) ( header("X-Accel-Redirect: " . $file); header("Content-Type: application/octet-stream"); ​​header("Content -Disposition: attachment; filename=" . basename($file)); exit; ) )
Більше інформації на сторінці офіційної документації

особливості:

  • Скрипт завершується одразу після виконання всіх інструкцій
  • Фізично файл відправляється модулем самого веб-сервера, а не PHP
  • Мінімальне споживання пам'яті та ресурсів сервера
  • Максимальна швидкодія

Update:Хабраюзер ilyaplot дає слушну пораду, що краще слати не application/octet-stream, а реальний mime type файлу. Наприклад, це дозволить браузеру підставити потрібні програми у діалог збереження файлу.

Для того, щоб зробити систему завантаження картинки або будь-якого іншого файлу на сервер, використовується HTML-форма і PHP-скрипт обробки даних, відправлених цією формою. Саме таким способом реалізовані різноманітні сервіси, що підтримують завантаження файлів на сервер. Реалізується вона подібно до звичайної форми відправлення даних на сервер.

HTML форма відправлення файлу

Найпростіша форма завантаження файлу:





В результаті отримаємо форму, що містить поле для вибору файлу і кнопку, яка надсилає дані форми на сервер:

Параметр entypeотримує у цій формі значення multipart/form-data, що визначає, що у цій формі буде виконано відправлення бінарних даних, тобто. файлу. Якщо це значення не вказати, то за умовчанням форма буде виконуватися як надсилання текстової інформації.

Параметр MAX_FILE_SIZE, Вказаний у формі визначає максимальний розмір файлу, заданий у байтах. За замовчуванням цей розмір визначається параметрами сервера.

Для вказівки завантажуваного файлу тег повинен містити тип "file", а також для подальшої роботи PHP-скрипту слід зазначити значення "name".

Надсилання даних форми виконується тегом із типом "submit". Він відображається звичайною кнопкою.

PHP код збереження файлу

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

У коді, що приймає, дані про файл містяться в суперглобальному масиві $_FILES. Відповідно, переглянути відомості про відправлений з форми файл можна в $_FILES["my_file"]. Такий масив містить таку інформацію:

Після отримання цієї інформації на сервері файл повинен бути скопійований в постійну директорію, т.к. тимчасовий файл після завершення скрипта буде автоматично видалено.

Копіювання виконується функцією copy() , параметрами якої є ім'я вихідного файлу (для цього випадку ім'я тимчасового файлу - $_FILES["my_file"]["tmp_name"]) та ім'я кінцевого файлу.

У результаті має вийти наступний код:

// Вказівка ​​директорії та імені нового файлу на сервері
$new_file = "/upload_files/" .$_FILES["uploadfile" ]["name" ];

// Копіювання файлу
if (copy($_FILES["uploadfile" ]["tmp_name" ], $new_file)) (
echo "Файл завантажений на сервер";
} else (
echo "Помилка під час завантаження файлу";
?>

Копіювання файлу має виконуватися в існуючу папку на сервері з наявними правами на створення в ній файлів.

У цьому прикладі ім'я файлу вказується тим самим, як і у вихідного файлу, що завантажується. У реалі дуже часто ім'я задається відповідно до власних вимог, найчастіше використовуючи дату і час завантаження, що забезпечує унікальність назви файлу. Це дозволяє звести зберігання та обробку файлів до будь-якого єдиного стандарту. Тут, звичайно, з'являються деякі додаткові завдання зі зберігання вихідної назви в БД, якщо це потрібно або визначення розширення файлу, що завантажується . Але в такому випадку буде менше проблем з кодуванням назви фала, а так само цифрову назву фала можна використовувати для зручного формування піддиректорій для зберігання фалів, що завантажуються.

Функція copy() повертає значення true, якщо копіювання виконано успішно та False при виникненні помилки у процесі копіювання.

При вдалому завершенні копіювання із завантаженим на сервер файлом можна виконувати будь-які необхідні дії.

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

Вихідні файли поточної статті ви можете завантажити на .

Почнемо зі створення форми, в якій буде присутнє поле для завантаження файлу. На що тут варто звернути увагу? По-перше, поле для відправки файлу повинно мати спеціальний тип - type = "file". По-друге, файл може бути відправлений тільки в тілі запиту, тому метод GET для відправки форми не підійде, потрібно використовувати метод POST — method=»post». Ну і по-третє, для форми необхідний спеціальний атрибут enctype з певним значенням - enctype = multipart / form-data. Без цього атрибута файл просто не буде надіслано.

Виходячи з озвученого вище, наш код буде приблизно таким:

< form class = "form-horizontal" method = "post" enctype = "multipart/form-data" action = "file.php" >

< div class = "form-group" >

< label for = "name" class = "col-sm-2 control-label" >Назвафайлу< / label >

< div class = "col-sm-8" >

< input type = "text" id = "name" class = "form-control" name = "name" placeholder = "Назва файлу" >

< / div >

< / div >

< div class = "form-group" >

< label for = "file" class = "col-sm-2 control-label" >Файл< / label >

< div class = "col-sm-8" >

< input type = "file" name = "file" id = "file" >

< / div >

< / div >

< div class = "form-group" >

< div class = "col-sm-offset-2 col-sm-8" >

< button type = "submit" id = "submit" class = "btn btn-primary" >Відправити< / button >

< div > < / div >

< / div >

< / div >

< / form >

В результаті ми отримаємо приблизно таку форму:

Поле для завантаження файлів виглядає не дуже привабливо, проте, зі своїм завданням упорається без проблем: файл можна прикріпити та відправити на сервер. У наступній статті ми спробуємо красиво оформити поле для завантаження файлу, а поки перевіримо, чи завантажується файл. Як бачимо, форма буде відправлена ​​у файл file.php, який вказаний в атрибуті action. Давайте створимо цей файл.

Радий бачити Вас на сторінках сайту. Сьогодні поговоримо про реалізацію завантаження файлів на сервер. Тема досить цікава т.к. багатьох новачків цікавить це питання.

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

Для того, щоб завантажити файл на сервер, потрібно створити форму для завантаження файлів. У принципі дана форма не дуже відрізняється від звичайної форми з текстовими полями, за винятком, що typeбуде не text, а file(оскільки ми завантажуємо файли) і в самій формі додасться атрибут enctype="multipart/form-data". Entypeвизначає вид кодування, яке браузер застосовує до параметрів форми.

PHP - Завантаження файлів на сервер своїми руками

Демо: Завантаження файлів на сервер

Завантажте фотографії на сервер



Форму завантаження файлів ми зробили саме час написати простий обробник для завантаження файлів на сервер. Визначимо відразу, що вантажити будемо лише графічні файли з типом jpeg, png, gif. Після того як ми визначили типи файлів для завантаження на сервер, нам потрібно створити папку на сервері, куди ми будемо складати наші файли. У моєму прикладі це папка image, в ній ми складатимемо наші файли.

"Помилка не виникла, файл був успішно завантажений на сервер. ", 1 => "Розмір прийнятого файлу перевищив максимально допустимий розмір, який заданий директивою upload_max_filesize конфігураційного файлу php.ini.", 2 => "Розмір файлу, що завантажується, перевищив значення MAX_FILE_SI у HTML-формі.", 3 => "Завантажуваний файл був отриманий лише частково.", 4 => "Файл не був завантажений.", 6 => "Відсутня тимчасова папка. Додано в PHP 4.3.10 та PHP 5.0.3 ."); //Визначаємо типи файлів для завантаження $fileTypes = array("jpg" => "image/jpeg", "png" => "image/png", "gif" => "image/gif");//Якщо натиснута кнопка завантажити if(isset($_POST["upload"])) ( // Перевіряємо порожні дані чи ні if(!empty($_FILES))) ( //Перевіряємо на помилки if($_FILES["files") ]["error"] > 0) $err = $errUpload[$_FILES["files"]["error"]]; //Перевірити тип файлу для завантаження if(!in_array($_FILES["files"][" type"], $fileTypes)) $err = "Цей тип файлу
". $_FILES["files"]["type"] ."

не підходить для завантаження!"; //Якщо немає помилок то вантажимо файл if(empty($err)) ( $type = pathinfo($_FILES["files"]["name"]); $name = $uploadDir ." /". uniqid("files_") .".". $type["extension"]; move_uploaded_file($_FILES["files"]["tmp_name"],$name); //Скидаємо POST параметри header("Location : http://". $_SERVER["HTTP_HOST"] ."/less/uploads/uploads.php?name=". $name); exit; ) else echo implode(" ", $err); ) ) //Повідомлення про успішне завантаження файлу на сервер if(isset($_GET["name"]))) echo "Файл

".htmlentities($_GET["name"]) ."< count($imgDir); $i++) { if($i % 2 == 0) echo "
успішно завантажений! // Виводимо картинки з каталогу $imgDir = array_values(array_diff(scandir($uploadDir), array("..", ".")))); for($i = 0; $i

"."\n"; echo "

"."\n"; ) echo " "."\n"; echo " http://". $_SERVER["HTTP_HOST"] ." "; ?>

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