Лекція № 9 Тема: Завантаження файлів План Multipart-форми та їх опис. Обробка multipart-форм. Multipart-форми і їх опис Завантаження файлів на сервер по протоколу HTTP здійснюється набагато чаші, чим ви можете подумати: - Web-інтерфейси поштових сервісів дозволяють додати до листа вкладення, а для цього потрібно спершу завантажити файл на сервер, а тільки після цього додавати до листа. - Інтерактивні фотогалереї і фотоальбоми просто не можуть існувати без механізму завантаження файлів. - Web-інтерфейси засобів управління контентом, які використовуються для управління сайтом, дозволяють завантажувати файли на сервер у вказаний каталог. Завантаження файлу на сервер здійснюється за допомогою так званої multipart-форми, в якій є поле завантаження файлу, — <input type=file>. При цій якості параметра enctype указується значення multipart/form-data: <form action=upload.php method=POST enctype=multipart/form-data> <input type=file name=UFile> Ім'я файлу на сервері <Input type=text name=Filename> <input type=submit name=upload value=3агрузить> </form>
Як виглядає Multipart-форма можна подивитися на мал Multipart-форма Multipart-форми зазвичай використовують метод передачі POST. Як видно з вищенаведеного прикладу дана форма зазвичай має два поля: Поле файлу вибору файлу для закачування <INPUT type=File>. Поле вказівки імені файлу, яке він повинен буде мати на сервері <INPUT type=text>. Сценарій завантаження файлів на сервер. Обробка multipart-форм Перш, ніж приступити до написання сценарію завантаження файлу, потрібно відредагувати файл конфігурації /etc/php.ini, щоб вирішити завантаження файлів. Відкрийте файл конфігурації і знайдіть секцію File uploads. У ній будуть три параметри: file_uploads = On — вирішує завантаження файлів на сервер по протоколу HTTP. upload_tmp_dir = /tmp — встановлює каталог для тимчасового зберігання завантажених файлів. upIoad_max_fiIesize — 2М — встановлює максимальний об'єм файлів які можуть бути завантажені. Якщо ваш Web-сервер працює під управлінням операційної системи Linux, потрібно перезапустити сервіс: service httpd restart Під Windows 9x/NT нічого робити не потрібно, оскільки РНР не вбудовується, як модуль в Apache. Як же РНР обробляє Multipart-форми? Отримавши файл, він зберігає його в тимчасовому каталозі upload_tmp_dir, ім'я файлу вибирається випадковим чином. Потім він створить чотири глобальних змінних: $UFile (так називається поле завантаження файлу) — містить ім'я файлу I в тимчасовому каталозі, наприклад, /tmp/phpJ6r5eR. $UFiIe_name — ім'я файлу до його відправки на сервер, наприклад | /home/den/water.png або c:\water.png. $UFiIe_size — розмір прийнятого файлу в байтах. $UFiIe_type — тип прийнятого файлу (якщо браузер зміг його опреде- ] лити), наприклад, image/png, image/jpeg, text/html. Після завершення роботи сценарію тимчасовий файл буде видалений. Це означає, що ми повинні його скопіювати в інше місце до завершення роботи сценарію. Тобто алгоритм роботи сценарію завантаження файлів такий: Якщо не натиснута кнопка "Submit" — відобразити форму завантаження файлу. 1 Якщо кнопка "Submit" натиснута, то файл вже буде завантажений на сервер і j його ім'я буде в змінній $UFile. В цьому випадку сценарій винен відразу скопіювати файл з ім'ям $UFile у який-небудь каталог (ви повинні мати права запису в цей каталог). Ви НЕ можете зберегти ім'я файлу в Cookies і скопіювати його при наступному запуску сценарію — файлу з ім'ям $UFile вже не буде — це звичайний тимчасовий файл і він буде видалений при завершенні роботи сценарію. Копіювання проводиться функцією copy(): copy($UFile, "/var/www/html/uploads/".basename($UFile_name) ); Потрібно використовувати тільки функцію копіювання. Використовувати функцію переміщення немає ніякого сенсу, оскільки: Тимчасовий файл буде видалений автоматично. Якщо тимчасовий каталог знаходиться на іншому носієві, ми отримаємо повідомлення про помилку. Припустимо, що нам потрібно завантажити файл в каталог uploads, який знаходиться в кореневому каталозі Web-сервера (каталозі DocumentRoot). // Про всяк випадок створюємо каталог. Якщо він вже створений, // повідомлення про помилку буде // пригнічене оператором @ @mkdir("uploads",0777) ; // Копіюємо файл з /tmp в uploads // Ім'я файлу буде таким же, як до відправки на сервер copy($UFile, "uploads/".basename($UFile_name));