2013-08-16 7 views
0

Я экспериментировал с Fine Uploader. Мне действительно интересны функции chunking и resume, но я испытываю трудности с переносом файлов на серверную сторону;fine-uploader Слияние сторон сервера PHP

Что я нашел, так это то, что я должен разрешить пустое расширение файла на стороне сервера, чтобы разрешить загрузку фрагментов, иначе загрузка завершится неудачно с неизвестным типом файла. Он загружает четкие фрагменты с именами файлов, такими как «blob» и «blob63» (без расширения файла), однако он не объединяет их при завершении загрузки.

Любая помощь или указатели будут оценены.

$('#edit-file-uploader').fineUploader({ 
      request: { 
       endpoint: 'upload.php' 
      }, 
      multiple: false, 
      validation:{ 
       allowedExtentions: ['stl', 'obj', '3ds', 'zpr', 'zip'], 
       sizeLimit: 104857600 // 100mb * 1024 (kb) * 1024 (bytes) 
      }, 
      text: { 
       uploadButton: 'Select File' 
      }, 
      autoUpload: false, 
      chunking: { 
       enabled: true 
      }, 
      callbacks: { 
       onComplete: function(id, fileName, responseJSON) { 
        if (responseJSON.success) { 
        /** some code here **?? 
        } 
      } 

    }); 

И это скрипт на стороне сервера (PHP):

// list of valid extensions, ex. array("stl", "xml", "bmp") 
$allowedExtensions = array("stl", ""); 
// max file size in bytes 
$sizeLimit = null; 

$uploader = new qqFileUploader($allowedExtensions, $sizeLimit); 

// Call handleUpload() with the name of the folder, relative to PHP's getcwd() 
$result = $uploader->handleUpload('uploads/'); 

// to pass data through iframe you will need to encode all html tags 
echo htmlspecialchars(json_encode($result), ENT_NOQUOTES); 

/******************************************/ 



/** 
* Handle file uploads via XMLHttpRequest 
*/ 
class qqUploadedFileXhr { 
    /** 
    * Save the file to the specified path 
    * @return boolean TRUE on success 
    */ 
    public function save($path) {  
     $input = fopen("php://input", "r"); 
     $temp = tmpfile(); 
     $realSize = stream_copy_to_stream($input, $temp); 
     fclose($input); 

     if ($realSize != $this->getSize()){    
      return false; 
     } 

     $target = fopen($path, "w");   
     fseek($temp, 0, SEEK_SET); 
     stream_copy_to_stream($temp, $target); 
     fclose($target); 

     return true; 
    } 

    /** 
    * Get the original filename 
    * @return string filename 
    */ 
    public function getName() { 
     return $_GET['qqfile']; 
    } 

    /** 
    * Get the file size 
    * @return integer file-size in byte 
    */ 
    public function getSize() { 
     if (isset($_SERVER["CONTENT_LENGTH"])){ 
      return (int)$_SERVER["CONTENT_LENGTH"];    
     } else { 
      throw new Exception('Getting content length is not supported.'); 
     }  
    } 
} 

/** 
* Handle file uploads via regular form post (uses the $_FILES array) 
*/ 
class qqUploadedFileForm { 

    /** 
    * Save the file to the specified path 
    * @return boolean TRUE on success 
    */ 
    public function save($path) { 
     return move_uploaded_file($_FILES['qqfile']['tmp_name'], $path); 
    } 

    /** 
    * Get the original filename 
    * @return string filename 
    */ 
    public function getName() { 
     return $_FILES['qqfile']['name']; 
    } 

    /** 
    * Get the file size 
    * @return integer file-size in byte 
    */ 
    public function getSize() { 
     return $_FILES['qqfile']['size']; 
    } 
} 

/** 
* Class that encapsulates the file-upload internals 
*/ 
class qqFileUploader { 
    private $allowedExtensions; 
    private $sizeLimit; 
    private $file; 
    private $uploadName; 

    /** 
    * @param array $allowedExtensions; defaults to an empty array 
    * @param int $sizeLimit; defaults to the server's upload_max_filesize setting 
    */ 
    function __construct(array $allowedExtensions = null, $sizeLimit = null){ 
     if($allowedExtensions===null) { 
      $allowedExtensions = array(); 
     } 
     if($sizeLimit===null) { 
      $sizeLimit = $this->toBytes(ini_get('upload_max_filesize')); 
     } 

     $allowedExtensions = array_map("strtolower", $allowedExtensions); 

     $this->allowedExtensions = $allowedExtensions;   
     $this->sizeLimit = $sizeLimit; 

     $this->checkServerSettings();  

     if(!isset($_SERVER['CONTENT_TYPE'])) { 
      $this->file = false;  
     } else if (strpos(strtolower($_SERVER['CONTENT_TYPE']), 'multipart/') === 0) { 
      $this->file = new qqUploadedFileForm(); 
     } else { 
      $this->file = new qqUploadedFileXhr(); 
     } 
    } 

    /** 
    * Get the name of the uploaded file 
    * @return string 
    */ 
    public function getUploadName(){ 
     if(isset($this->uploadName)) 
      return $this->uploadName; 
    } 

    /** 
    * Get the original filename 
    * @return string filename 
    */ 
    public function getName(){ 
     if ($this->file) 
      return $this->file->getName(); 
    } 

    /** 
    * Internal function that checks if server's may sizes match the 
    * object's maximum size for uploads 
    */ 
    private function checkServerSettings(){   
     $postSize = $this->toBytes(ini_get('post_max_size')); 
     $uploadSize = $this->toBytes(ini_get('upload_max_filesize'));   

     if ($postSize < $this->sizeLimit || $uploadSize < $this->sizeLimit){ 
      $size = max(1, $this->sizeLimit/1024/1024) . 'M';    
      die(json_encode(array('error'=>'increase post_max_size and upload_max_filesize to ' . $size)));  
     }   
    } 

    /** 
    * Convert a given size with units to bytes 
    * @param string $str 
    */ 
    private function toBytes($str){ 
     $val = trim($str); 
     $last = strtolower($str[strlen($str)-1]); 
     switch($last) { 
      case 'g': $val *= 1024; 
      case 'm': $val *= 1024; 
      case 'k': $val *= 1024;   
     } 
     return $val; 
    } 

    /** 
    * Handle the uploaded file 
    * @param string $uploadDirectory 
    * @param string $replaceOldFile=true 
    * @returns array('success'=>true) or array('error'=>'error message') 
    */ 
    function handleUpload($uploadDirectory, $replaceOldFile = FALSE){ 
     if (!is_writable($uploadDirectory)){ 
      return array('error' => "Server error. Upload directory isn't writable."); 
     } 

     if (!$this->file){ 
      return array('error' => 'No files were uploaded.'); 
     } 

     $size = $this->file->getSize(); 

     if ($size == 0) { 
      return array('error' => 'File is empty'); 
     } 

     if ($size > $this->sizeLimit) { 
      return array('error' => 'File is too large'); 
     } 

     $pathinfo = pathinfo($this->file->getName()); 
     $filename = $pathinfo['filename']; 
     //$filename = md5(uniqid()); 
     $ext = @$pathinfo['extension'];  // hide notices if extension is empty 

     if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){ 
      $these = implode(', ', $this->allowedExtensions); 
      return array('error' => 'File has an invalid extension, it should be one of '. $these . '.'); 
     } 

     $ext = ($ext == '') ? $ext : '.' . $ext; 

     if(!$replaceOldFile){ 
      /// don't overwrite previous files that were uploaded 
      while (file_exists($uploadDirectory . DIRECTORY_SEPARATOR . $filename . $ext)) { 
       $filename .= rand(10, 99); 
      } 
     } 

     $this->uploadName = $filename . $ext; 

     if ($this->file->save($uploadDirectory . DIRECTORY_SEPARATOR . $filename . $ext)){ 
      return array('success'=>true); 
     } else { 
      return array('error'=> 'Could not save uploaded file.' . 
       'The upload was cancelled, or server error encountered'); 
     } 

    }  
} 

ответ

1

Для того, чтобы справиться с блочными запросами, вы должны хранить каждый кусок отдельно в вашей файловой системе.
Как вы называете эти куски или где вы их храните, зависит от вас, но я предлагаю вам назвать их, используя UUID, предоставленный Fine Uploader, и добавьте параметр номера детали, включенный в каждый запрошенный фрагмент. После того, как последний кусок был отправлен, объедините все куски в один файл с собственным именем и верните стандартный ответ успеха, как описано в документации Fine Uploader. Первоначальное имя файла по умолчанию передается с параметром qqfilename с каждым запросом. Это также обсуждается в docs и blog.

Не похоже, что вы пытались обработать серверные части. Существует PHP example в репозитории Widen/fine-uploader-server, который вы можете использовать. Кроме того, в документации есть раздел «серверная», в котором объясняется, как обрабатывать фрагменты подробно. Я предполагаю, что вы этого не читали. Посмотрите.) В репозитории Widen/fine-uploader-server, который вы можете использовать. Кроме того, в документации есть раздел «серверная», в котором объясняется, как обрабатывать фрагменты подробно. Я предполагаю, что вы этого не читали. Взгляни.

Обратите внимание, что, начиная с Fine Uploader 3.8 (установите для выпуска ОЧЕНЬ скоро), вы сможете делегировать всю загрузку на серверную загрузку на Amazon S3, поскольку Fine Uploader обеспечит тесную интеграцию с S3, который отправит все ваши файлы прямо из вашего браузера, без необходимости беспокоиться о создании документа политики, создании вызовов REST API, обработке ответов с S3 и т. д. Я упоминаю об этом, поскольку использование S3 означает, что вам никогда не придется беспокоиться о том, как обрабатывать такие вещи, как chunked requests on ваш сервер снова.

Смежные вопросы