Загрузка директорий с помощью webkitdirectory
Как известно, последний выпуск Google Chrome поддерживает функцию загрузки целый директорий на сервер. Это осуществляется с помощью атрибута webkitdirectory указанного у тега input типа file. В этой статье я попробую реализовать эту функцию и рассказать Вам о результате.
Для начала я написал HTML код формы загрузки:
<form action="directory-upload.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="uploaded" value="1" />
<label>Выберите директорию:</label>
<input type="file" name="directory[]" webkitdirectory />
<input type="submit" value="Загрузить" />
</form>
Тут нужно обратить внимание, что имя тега input с атрибутом webkitdirectory я назвал directory[]. Это необходимо чтобы браузер при выборе нескольких файлов в папке правильно поместил их в массив $_FILES. Если назвать просто directory, то загрузится только один из выбранных файлов. Кстати совершенно необязательно называть его directory - можете выбрать любое другое имя.
Тег input по имени uploaded нужен мне чтобы определять, загрузил ли пользователь уже файлы, либо страница с кодом открыта в первый раз и массив $_FILES пока пуст.
Посмотрим что получилось:
Сама форма выглядит так же как при загрузке одиночного файла, однако при нажатии на кнопку высвечивается удобное окно для выбора папки для загрузки.
Теперь разберемся с серверной частью. Чтобы посмотреть как выглядит массив $_FILES при загрузке директорий я написал такой код:
if(isset($_POST['uploaded'])){
if(!empty($_POST['uploaded'])){
$uploaded = htmlspecialchars(stripslashes($_POST['uploaded']));
if($uploaded==1){
print '<pre>';
print_r($_FILES);
print '</pre>';
}
}
}
При загрузке на сервер четырех файлов, на экран вывелось содержание массива $_FILES:
Array
(
[directory] => Array
(
[name] => Array
(
[0] => Ancistrus.doc
[1] => Апистограмма.doc
[2] => Атерина красная.doc
[3] => брохис.doc
)
[type] => Array
(
[0] => application/msword
[1] => application/msword
[2] => application/msword
[3] => application/msword
)
[tmp_name] => Array
(
[0] => /tmp/phpwXr0Vg
[1] => /tmp/phpiK6tfH
[2] => /tmp/phpWKg0y7
[3] => /tmp/phpgLHySx
)
[error] => Array
(
[0] => 0
[1] => 0
[2] => 0
[3] => 0
)
[size] => Array
(
[0] => 25088
[1] => 25088
[2] => 24064
[3] => 22016
)
)
)
Теперь мы знаем структуру массива и можем поочередно переместить файлы из временной папки - туда куда нам нужно.
for($i=0;$i<count($_FILES['directory']['name']);$i++){
if($_FILES['directory']['error'][$i]==0){
move_uploaded_file($_FILES['directory']['tmp_name'][$i], "files/".$_FILES['directory']['name'][$i]);
}
else{
echo "<p>Ошибка при загрузке файла</p>";
}
}
}
}
Только не забудьте создать директорию files и дать php права на запись. Теперь Вы умеете загружать целый директории на сервер!
Теперь давайте немного поэкспериментируем и добавим в форму следующую строчку:
<input type="hidden" name="MAX_FILE_SIZE" value="25000" />
Вы можете протестировать получившийся код и понять, что атрибут value указывает на максимальный размер каждого файла для загрузки. На данный момент я не нашел атрибута, который бы указывал максимально разрешенное количество файлов для загрузки, но это можно сделать либо с помощью FilesAPI, либо уже на сервере.
Кстати на данный момент атрибут webkitdirectory не входит в спецификацию HTML5 и является собственной разработкой Google. Я связался с представителями W3C и они сказали что если эта функция войдет в окончательный вариант спецификации, то скорее всего называться будет не webkitdirectory а просто directory. Так что не следует злоупотреблять этим атрибутом у Вас на сайте - пока её поддерживает только Google Chrome 7.
На этом у меня все. Пример полученного скрипта Вы можете увидеть тут: http://html5blog.ru/examples/directory-upload.php