ThemeForest имеет приятную особенность; Это позволяет авторам загружать zip-файлы, содержащие скриншоты их тем. Затем скрипт извлекает эти файлы и отображает изображения соответственно. Хотя я сомневаюсь, что разработчики использовали PHP для выполнения этой задачи … это то, что мы собираемся использовать!
Что мы должны делать
- Создайте простую форму загрузки, которая позволяет пользователю выбрать ZIP-файл.
- Убедитесь, что пользователь выбирает zip-файл, а затем сохраните его как уникальный файл.
- Извлеките содержимое из zip-файла и сохраните его в определенной папке.
- Удалите zip-файл и отобразите его содержимое.
Шаг 1: Создание формы загрузки
- Создайте новый файл и сохраните его как index.html в корне вашего решения.
- Далее мы создадим простую форму. Вставьте следующее в.
1
2
3
4
|
<form enctype=»multipart/form-data» action=»» method=»post»>
<input type=»file» name=»fupload» /><br />
<input type=»submit» value=»Upload Zip File» />
</form>
|
Каждый раз, когда вы разрешаете пользователям загружать файлы, вы должны установить «enctype» тега формы равным «multipart / form-data» . Затем мы установим действие, равное той же странице, и метод, равный post.
Чтобы все было как можно проще, у нас есть только файл ввода и кнопка отправки. Обратите внимание, что мы установили имя входного файла на «fupload». Мы скоро будем использовать это значение, чтобы определить, была ли страница отправлена обратно.
Шаг 2: Написание PHP
В самом верху вашей страницы index.php перед объявлением типа документа вставьте следующее:
1
2
3
4
5
|
<?php
if(isset($_FILES[‘fupload’])) {
$filename = $_FILES[‘fupload’][‘name’];
$source = $_FILES[‘fupload’][‘tmp_name’];
$type = $_FILES[‘fupload’][‘type’];
|
Давайте сделаем это шаг за шагом.
- Если задан входной тег с именем «fupload», выполните следующий код, в противном случае ничего не делайте.
- Теперь нам нужно создать несколько переменных. Нам нужно захватить имя загруженного файла, каталог, в котором файл временно хранится, и тип файла, который был выбран.
Давайте предположим, что пользователь выбирает файл с именем «myPics.zip».
- $ _FILES [‘fupload’] [‘name’] = «myPics.zip»
- $ _FILES [‘fupload’] [‘tmp_name’] = некоторый временный каталог на сервере.
- $ _FILES [‘fupload’] [‘type’] = «application / zip». (Это значение может меняться в зависимости от того, из какого браузера был загружен файл.
Далее, давайте разберем имя файла на две части: имя и расширение.
1
2
|
$name = explode(‘.’, $filename);
$target = ‘extracted/’ .
|
Продолжая наш пример файла «myPics.zip» — $ name [0] будет равно «myPics». $ name [1] будет равно «zip».
Далее мы создаем новую переменную с именем «$ target». Это будет папка, в которую будет сохранен наш файл. Чтобы гарантировать, что другой пользователь с тем же именем «myPics» не перезаписывает свои файлы, мы должны сохранить эти файлы в уникальном месте. Для выполнения этой задачи мы реализуем функцию time (). Если мы добавим это значение к имени загруженного файла, мы можем быть уверены, что получим уникальное имя папки!
$ target = «extract / myPics-02151985 /»
Шаг 3. Убедитесь, что выбран файл Zip
Сразу после вашей переменной $ target вставьте следующее:
1
2
3
4
5
6
7
8
|
$accepted_types = array(‘application/zip’, ‘application/x-zip-compressed’, ‘multipart/x-zip’, ‘application/s-compressed’);
foreach($accepted_types as $mime_type) {
if($mime_type == $type) {
$okay = true;
break;
}
}
|
- Мы начнем с создания массива с именем $ accept_types. Быстрый поиск в Google по «типам zip mime» принесет нам четыре значения: «application / zip», «application / x-zip-compress», «multipart / x-zip», «application / s-compress» . Каждый браузер имеет свой собственный способ регистрации типа файла. Мы должны обязательно проверить каждое значение в таких случаях.
- Для этого мы проверяем, имеет ли какой-либо из элементов в нашем массиве то же значение, что и «$ _FILES [‘fupload’] [‘type’]». Если они это сделают, мы установим нашу удобную переменную $ okay в значение handy-dandy, равное «true», и можем выйти из выражения «for» и быть уверенными, что пользователь фактически выбрал zip-файл.
К сожалению, Safari и Chrome не регистрируют тип для zip-файлов. Это создает проблему для нас. После небольшого исследования я не смог найти простое решение — без использования расширения (PEAR). Вместо этого мы позаботимся о том, чтобы имя файла как минимум заканчивалось на «zip». Следует отметить, что это не на 100% безопасно. Что если пользователь загрузил файл другого типа, который оканчивался на «zip»? Не стесняйтесь предлагать рекомендации! 🙂
1
|
$okay = strtolower($name[1]) == ‘zip’ ?
|
- Мы будем использовать троичный оператор, чтобы сохранить это утверждение до одной строки. Если расширение имени файла ($ name [1]) равно ‘zip’, мы установим для $ okay значение true. В противном случае оно будет равно «ложно».
Далее мы проверим, является ли $ okay ложным. Если это так, мы знаем, что файл «zip» не был выбран. В таких случаях мы скажем PHP умереть.
1
2
3
|
if(!$okay) {
die(«Please choose a zip file, dummy!»);
}
|
Шаг 4: Сохранение Zip-файла
1
2
3
4
5
6
7
8
|
mkdir($target);
$saved_file_location = $target .
if(move_uploaded_file($source, $saved_file_location)) {
openZip($saved_file_location);
} else {
die(«There was a problem. Sorry!»);
}
|
- Сначала нам нужно создать каталог, на который мы ссылаемся с нашей переменной $ target. Это легко сделать с помощью функции «mkdir».
- Далее, давайте попробуем переместить загруженный файл из временного каталога в наш каталог $ target. Если эта процедура была выполнена успешно, мы вызовем функцию «openZip».
Шаг 5: функция openZip ()
Создайте новую страницу и сохраните ее как «functions.php». Теперь добавьте следующий код:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
<?php
function openZip($file_to_open) {
global $target;
$zip = new ZipArchive();
$x = $zip->open($file_to_open);
if($x === true) {
$zip->extractTo($target);
$zip->close();
unlink($file_to_open);
} else {
die(«There was a problem. Please try again!»);
}
}
?>
|
Эта функция будет принимать один параметр: $ file_to_open. Этот параметр будет содержать расположение zip-файла, который мы пытаемся извлечь!
- Чтобы использовать класс ZipArchive (), вы должны сначала убедиться, что в вашем файле php.ini включен php_zip.dll. Просто найдите эту строку, а затем удалите точку с запятой.
- В любом классе нам нужно создать новый экземпляр объекта. Затем мы вызовем метод open и передадим местоположение файла, который должен быть открыт. При успешном выполнении этот метод вернет true. Если это так, мы извлечем содержимое zip-файла в папку. Мы уже создали путь к этой папке, когда создали переменную $ target. ( Примечание. Чтобы получить доступ к этой переменной, вам нужно добавить «global» перед переменной. Это скажет PHP выйти за пределы текущей функции и искать переменную $ target. ).
- Как только файлы будут извлечены, мы удалим zip-файл — так как он нам больше не нужен!
Помните — мы создали наш новый файл «functions.php», но мы должны включить его! Добавьте следующее в начало страницы index.php сразу после открывающего тега PHP.
1
|
require_once ‘functions.php’;
|
Повторяя содержание
То, что у нас пока, работает отлично! Но, просто чтобы дать вам обратную связь, давайте просканируем новый каталог и выведем на экран его содержимое. Вы должны удалить этот следующий блок кода из вашего проекта. Это только для тестирования. Если вы хотите сохранить его, отобразите информацию в теге body.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
$scan = scandir($target . $name[0]);
print ‘<ul>’;
for ($i = 0; $i<count($scan); $i++) {
if(strlen($scan[$i]) >= 3) {
$check_for_html_doc = strpos($scan[$i], ‘html’);
$check_for_php = strpos($scan[$i], ‘php’);
if($check_for_html_doc === false && $check_for_php === false) {
echo ‘<li>’ .
} else {
echo ‘<li><a href=»‘ . $target . $name[0] . ‘/’ . $scan[$i] . ‘»>’ .
}
}
}
print ‘</ul>’;
}
|
Я не буду слишком подробно останавливаться на этой последней части — так как в этом нет необходимости. Однако, если вы хотите получить полное объяснение, обязательно посмотрите соответствующий скринкаст! Чтобы быстро подвести итог, этот последний скрипт сканирует наш новый каталог и выводит неупорядоченный список, содержащий содержимое.
Законченный
Не слишком сложно, а? Это удобная функция, которая может быть легко внедрена в ваши проекты. Что вы думаете о безопасности, когда дело доходит до загрузки ZIP-файлов? Как мы можем быть уверены, что содержимое zip-файла не представляет опасности? Я хотел бы услышать мнение всех об этих последствиях для безопасности. При неправильном обращении хакер может нанести серьезный вред вашему серверу. Давайте обсудим это! Можно искать опасные типы файлов (файлы .htaccess) и удалять их.
Финальная страница Index.php
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
<?php
include ‘functions.php’;
if(isset($_FILES[‘fupload’])) {
$filename = $_FILES[‘fupload’][‘name’];
$source = $_FILES[‘fupload’][‘tmp_name’];
$type = $_FILES[‘fupload’][‘type’];
$name = explode(‘.’, $filename);
$target = ‘extracted/’ .
// Ensures that the correct file was chosen
$accepted_types = array(‘application/zip’,
‘application/x-zip-compressed’,
‘multipart/x-zip’,
‘application/s-compressed’);
foreach($accepted_types as $mime_type) {
if($mime_type == $type) {
$okay = true;
break;
}
}
//Safari and Chrome don’t register zip mime types.
$okay = strtolower($name[1]) == ‘zip’ ?
if(!$okay) {
die(«Please choose a zip file, dummy!»);
}
mkdir($target);
$saved_file_location = $target .
if(move_uploaded_file($source, $saved_file_location)) {
openZip($saved_file_location);
} else {
die(«There was a problem. Sorry!»);
}
// This last part is for example only.
$scan = scandir($target . $name[0]);
print ‘<ul>’;
for ($i = 0; $i<count($scan); $i++) {
if(strlen($scan[$i]) >= 3) {
$check_for_html_doc = strpos($scan[$i], ‘html’);
$check_for_php = strpos($scan[$i], ‘php’);
if($check_for_html_doc === false && $check_for_php === false) {
echo ‘<li>’ .
} else {
echo ‘<li><a href=»‘ . $target . $name[0] . ‘/’ . $scan[$i] . ‘»>’ .
}
}
}
print ‘</ul>’;
}
?>
<!DOCTYPE html PUBLIC «-//W3C//DTD XHTML 1.0 Strict//EN» «http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd»>
<html>
<head>
<title>How to Upload and Open Zip Files With PHP</title>
<meta http-equiv=»Content-Type» content=»text/html; charset=UTF-8″>
</head>
<body>
<div id=»container»>
<h1>Upload A Zip File</h1>
<form enctype=»multipart/form-data» action=»» method=»post»>
<input type=»file» name=»fupload» /><br />
<input type=»submit» value=»Upload Zip File» />
</form>
</div><!—end container—>
</body>
</html>
|
- Подпишитесь на RSS-канал NETTUTS, чтобы узнать о ежедневных новостях и статьях о веб-разработке.