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, чтобы узнать о ежедневных новостях и статьях о веб-разработке.

