【问题标题】:Upload a whole directory through an HTML form通过 HTML 表单上传整个目录
【发布时间】:2011-04-29 20:01:18
【问题描述】:

是否可以在浏览器中上传带有文件输入的文件夹?

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

【问题讨论】:

    标签: html forms file-upload directory


    【解决方案1】:

    请参阅swfupload - 一次上传多个文件的基于 Flash 的方式。反正不能上传文件夹,只能上传文件夹里的所有文件。

    【讨论】:

    【解决方案2】:

    可以通过拖放一次上传多个文件,无需任何浏览器插件。这是 HTML5 和 javascript 的新开发,因此您可能需要对旧版浏览器进行回退。

    它被称为“HTML5 drag and drop”。我还没有使用它,所以我不能给你示例代码,但是搜索那个短语,阅读链接的 Mozilla 博客文章可能会给你一些指导。

    【讨论】:

      【解决方案3】:

      使用 webkitdirectory 成为可能。

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

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

      【讨论】:

      • multiple 不适用于 webkitdirectorydirectory
      【解决方案4】:

      请试试这个上传文件夹:

      <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++;
                  }
              }
          }
      }
      

      `

      【讨论】:

      • 如何获取服务器上的文件夹?看起来它会上传文件夹内的所有文件,而没有关于文件夹结构/子文件夹的信息。请提出建议。
      • 有一个开放的 PHP 错误报告。仅通过 PHP 获取文件夹结构或多或少是不可能的。 bugs.php.net/bug.php?id=77372
      【解决方案5】:

      您可以使用tar 之类的内容归档目录,然后将其作为一个文件上传。但请注意,您可能会超过默认设置为 2MB 的 php upload max。这是可配置的。

      【讨论】:

        【解决方案6】:

        要在 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);
                    }
                }
            }
        }
        ?>
        

        【讨论】:

          【解决方案7】:

          仅使用 PHP 似乎无法上传文件夹,但 Javascript 可以检测文件夹,所以我通过执行以下两个步骤解决了它:

          1. 创建一个 Javascript 函数,该函数读取将要上传的目录和文件,并将其添加到将与 POST 一起发送的数组(我称为此文件结构)中。例如:

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

          Dropzone.js 中有一个类似的函数已经处理了这个我必须修改的函数(_addFilesFromDirectory())。但是您可以创建自己的函数来执行此操作。如果您需要更多帮助,请参阅此https://stackoverflow.com/a/20431117/6760554

          1. 在 PHP 中,您应该首先让您的文件上传到某个文件夹,在那里它们将被临时存储。上传文件后,您需要将 javascript 数组传递给 phpcode。 在那里,您需要迭代数组并创建文件夹,然后将上传的文件从临时文件夹移动到它们各自的位置。 例如:

            $_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);
                    }
            
                }
            }
            

          我希望这会有所帮助。

          【讨论】:

            【解决方案8】:

            如果您使用 dropzone: dropzone 扫描被删除目录和对应的子目录中的文件,向每个文件请求后端。 此文件原始完整路径已被捕获

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

            PD:示例中使用了 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 可以分别进行多次上传而不会出现问题,并且适用于您的用例。

            【讨论】:

              猜你喜欢
              • 2010-10-29
              • 2012-10-21
              • 2011-03-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-03-09
              • 2012-08-08
              • 2016-03-18
              相关资源
              最近更新 更多