Input multiple-2
По мотивам предыдущего поста. Чтобы Opera 9+ (а так же 3.5—6.05), Firefox 3.6+, Chrome 3.0.191.0+ и Safari 4.0.1+ позволили выбрать несколько файлов в диалоге загрузки файлов, нужно написать вот такой код:
<form enctype="multipart/form-data" method="post">
<input type="file" min="1" max="9999" name="file[]" multiple="true" />
<input type="submit" name="submit" />
</form>
Я указал «file[]» для того, чтобы PHP сразу разложил полученные файлы по массиву $_FILES. К сожалению, запрос от «Оперы» PHP понимает неверно, так как «Опера» шлёт такой запрос в формате multipart/mixed. К счастью, PHP в этом случае положит содержимое файлов одним MIME-куском прямо в $_POST[’file’][0], а там его уже можно разобрать (надеюсь, директива magic_quotes_gpc у вас отключена).
Я попробовал, это несложно. Для того, чтобы разобрать MIME-секцию, я использовал PECL-модуль mailparse (есть версия для Windows):
if (isset($_POST['file'], $_POST['file'][0])) {
if ($idx = strpos($_POST['file'][0], "\n")) {
$bound = substr($_POST['file'][0], 2, $idx-2);
$body = "MIME-Version: 1.0\nContent-type: multipart/form-data; boundary={$bound}\n\n".
$_POST['file'][0];
unset($_POST['file'][0]);
$f = &$_FILES['file'];
$f['name'] = $f['type'] = $f['tmp_name'] = $f['error'] = $f['size'];
$msg = mailparse_msg_create();
if (mailparse_msg_parse($msg, $body)) {
$i = 0;
foreach(mailparse_msg_get_structure($msg) as $st) {
$section = mailparse_msg_get_part($msg, $st);
$data = mailparse_msg_get_part_data($section);
if ($data['content-type'] == 'multipart/form-data') {
continue;
}
ob_start();
if (mailparse_msg_extract_part($section, $body)) {
$tmp = tempnam(sys_get_temp_dir(), 'php');
file_put_contents($tmp, ob_get_clean());
$f['name'][$i] = $data['disposition-filename'];
$f['type'][$i] = $data['content-type'];
$f['tmp_name'][$i] = $tmp;
$f['error'][$i] = 0;
$f['size'][$i] = filesize($tmp);
$i++;
} else {
ob_end_clean();
}
}
}
unset($f);
mailparse_msg_free($msg);
}
}
var_dump($_FILES); // результат помещатся в $_FILES, не забудьте удалить временные файлы после обработки!
У меня ожидается, что содержимое файлов будет передано как параметр «file[]» (в $_POST это будет $_POST[’file’][0]), но пример несложно переделать на любое другое имя или сделать это имя параметром.
Сайт лежал и комментарии пропали :-(
Про разбор формы — я вот так делал: http://masterspammer.livejournal.com/30260.html
Хорошее решение. В случае с админ интерфейсом и интранетом можно наплевать на Оперу
Восстановили сайт из бакапа что ли? Чёрт.
Как быть, если поле input-поле файла уже часть массива?
<input type=«file» name=«myform[myfile]» ...
Комментарий для sontar.livejournal.com:
<input type=«file» name=«myform[myfile][]» />