通过HTML表单上传整个目录

17

在浏览器中使用文件输入框上传整个文件夹是否可行?

我搜索了一下,发现这可能是浏览器的限制,可能需要使用Java Applet或Flash。

8个回答

26

使用webkitdirectory已经成为可能。

<input type="file" webkitdirectory directory multiple />

自Firefox 50、Chrome 30、Safari 11.1、Edge 14起就被支持,但截至2019年在大多数移动浏览器上不支持:https://caniuse.com/#feat=input-file-directory


4
multiplewebkitdirectorydirectory 不兼容。 - Apul Gupta

12
请尝试以下方法上传文件夹:

请尝试以下方法上传文件夹:

<form method="post" enctype="multipart/form-data">
    <input type="file" name="files[]" id="files" multiple="" directory="" webkitdirectory="" mozdirectory="">
    <input class="button" type="submit" value="Upload" />
</form>
`

$count = 0;
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
    foreach ($_FILES['files']['name'] as $i => $name) {
        if (strlen($_FILES['files']['name'][$i]) > 1) {
            if (move_uploaded_file($_FILES['files']['tmp_name'][$i], 'folder/'.$name)) {
                $count++;
            }
        }
    }
}

`


9
它如何在服务器上创建文件夹?似乎它会上传文件夹内的所有文件,但不会保留文件夹结构/子文件夹的信息。请提供建议。 - Apul Gupta
PHP存在一个未解决的Bug。仅通过PHP几乎不可能获取文件夹结构。https://bugs.php.net/bug.php?id=77372 - Björn Tantau

2
可以通过拖放方式上传多个文件,无需任何浏览器插件。这是HTML5和JavaScript的新发展,因此您可能需要为旧版浏览器提供备用方案。
它被称为“HTML5拖放”。我还没有使用过它,所以我不能给您示例代码,但搜索该短语并阅读链接的Mozilla博客文章可能会给您一些指导。

2

似乎无法仅使用PHP上传文件夹,但Javascript可以检测到文件夹,因此我通过以下两个步骤解决了这个问题:

  1. Create a Javascript function that reads the directory and files that will be uploaded and add this to a array(I called this Filestructure) that will be sent together with POST. For example:

    {
        'foldername/': {'file1.txt','file2.txt}, 
        'foldername/folder2': {'foo.txt', 'bar.png'} 
    }
    

在Dropzone.js中已经有一个类似的功能可以处理这个问题,不过我需要修改(_addFilesFromDirectory() )。但是你可以自己创建一个函数来处理这个问题。如果你需要更多帮助,请参考https://dev59.com/6nnZa4cB1Zd3GeqPwvZF#20431117

  1. In Php you should first let your files be uploaded to a certain folder where they will be stored temporary. After your files has been uploaded you then need to pass your javascript array to your phpcode. There you need to iterate the array and create the folders and then move your uploaded files from the temporary folder to their respective location. For example:

    $_filetree = $_POST['filetree'];
    
    function createFoldersAndMoveFiles($_filetree) 
    {
    
        $nFolders = count($_filetree);
    
        foreach ($_filetree as $folder => $files) {
            createFolder($folder);
            moveFiles($files, $folder);
    
        }
    }
    
    function moveFiles($_files, $_folder) {
    
        $source = 'tmpuploads/';
        $destination = 'mypath/';
    
        $nFiles = count($_files);
        for($i = 0; $i < $nFiles; $i++) {
            $file = $_files[$i];
            rename($source . $file, $destination .$_folder. '/' .$file);
          }
    }
    
    function createFolder($foldername) {
        $folders = explode("/", $foldername);
    
        $path = 'mypath/';
        $nFolders = count($folders);
        for($i = 0; $i < $nFolders; $i++){
            $newFolder = '/' . $folders[$i];
            $path .= $newFolder;
    
            if (!file_exists($path) && !is_dir($path)) {
                mkdir($path);
            }
    
        }
    }
    
我希望这可以帮到您。
注:保留HTML标签。

1

要在PHP中上传文件夹,请按照以下步骤进行操作:

<form id="form1" action="myCurrent.php" method="post">
<label>Upload All Files From Folder</label> <br/>
<input id="input" name="input[]" type="file" multiple webkitdirectory >
<div id="errorBlock" class="help-block"></div> <br/>

<input type="submit" name="btnDesFolder" id="btnDesFolder" value="send file" />
</form>

<?php
if(isset($_POST['btnDesFolder'])){
    $myFiles = $_POST['input-folder-2'];

    if(isset($_POST['input-folder-2'])){
        $files = scandir("path/to/your/folder");
        $oldfolder = "path/to/your/folder/";

        $newfolder = "path/to/new/folder";

        foreach($files as $fname) {
            if($fname != '.' && $fname != '..' && $fname != 'index.php') {
                rename($oldfolder.$fname, $newfolder.$fname);
            }
        }
    }
}
?>

0
你可以使用类似于tar的工具将目录打包成一个文件,然后上传。但是要小心,你可能会超过默认设置为2MB的php上传最大限制。不过这个限制是可以配置的。

0

请参考swfupload - 一种基于Flash的上传多个文件的方式。无论如何,无法上传整个文件夹,只能上传文件夹中的所有文件。


1
由于Flash不再受支持,因此此内容已过时。https://theblog.adobe.com/adobe-flash-update/ - Paul Oskar Mayer

0

如果您使用Dropzone: Dropzone会扫描放置的目录及其子目录中的文件,并为每个文件向后端发出请求。 该文件的原始完整路径被捕获。

https://www.dropzonejs.com/#event-sending

注:此示例使用了 lodash (_.without):

sendingEvent(file, xhr, formData){

    if (file.fullPath) { //file.fullPath only exist if file is inside a directory
        var directoryStructure = _.without(file.fullPath.split("/"), file.name);
        formData.append('directory-structure', directoryStructure.join(",") );
    }
}

您在请求中收到了以下内容:

  • 目录结构:路径
  • 文件:二进制

现在您可以在后端处理此文件夹名称。 Dropzone 可以单独进行多个上传,没有问题,并且对您的用例非常有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接