2016-11-06 9 views
1

Итак, я пытаюсь получить загрузку Chunked для работы над проектом, над которым я работаю, я довольно новичок в вещах, на самом деле для всех интенсивных целей вы можете считать меня полным нобом, который учит себя, я использую шаблон ручной загрузки с веб-сайта и файлы примеров традиционной серверной стороны, чтобы получить представление о том, как работает код и пытаться собрать их вместе в полнофункциональный пример для меня. Я смог заставить большинство работать.Загрузка файлов в Fine-Uploader, неспособность объединить/объединить куски после успешной загрузки

Мне удалось загрузить его в папку с файлами успешно, если я загружаю файл без chunking, он входит в каталог моих файлов, однако, если я использую chunking, он работает, чтобы разбить файл и загрузить его в в моем каталоге Chunks, но я не могу понять, как заставить его поместить куски обратно вместе и поместить его в каталог Files.

Моя консоль Firefox дает мне этот ответ и останавливается после завершения загрузки файла кусками независимо от того, есть ли у меня конечная точка успеха, включенная в мой код, или нет, что заставляет меня думать, что это связано с тем, что конечная точка успеха не была правильно настроена или что-то в этом роде.

[Fine Uploader 5.11.8] All chunks have been uploaded for 0 - finalizing....fine-uploader.js:162:21 
[Fine Uploader 5.11.8] Received response status 200 with body: {"success":true,"uuid":"79e7db33-9609-49cd-bcb1-2606bea6abd7","uploadName":null}fine-uploader.js:162:21 
[Fine Uploader 5.11.8] Finalize successful for 0 

Я провел около 2 дней исследования это, без толку, я, кажется, не получаю ошибки, но, как я сказал, что я довольно много Noob, когда речь заходит о понимании это сам , Любая помощь очень ценится.

Вот мой Uploader код тела

<body> 
    <!-- Fine Uploader DOM Element 
    ====================================================================== --> 
    <div id="fine-uploader-manual-trigger"></div> 

    <!-- Your code to create an instance of Fine Uploader and bind to the DOM/template 
    ====================================================================== --> 
    <script> 
     var manualUploader = new qq.FineUploader({ 
       debug: true, 
      element: document.getElementById('fine-uploader-manual-trigger'), 
      template: 'qq-template-manual-trigger', 
      request: { 
       endpoint: 'endpoint.php' 
      }, 
       chunking: { 
       enabled: true 
       }, 
       success: { 
      endpoint: "endpoint.php?done" 
       }, 
       resume: { 
       enabled: true 
       }, 
      thumbnails: { 
       placeholders: { 
        waitingPath: 'images/waiting-generic.png', 
        notAvailablePath: 'images/not_available-generic.png' 
       } 
      }, 
      autoUpload: false, 
       showMessage: function(message) { //show message if any error occur during upload process 
       alert(message); 
      } 


     }); 

     qq(document.getElementById("trigger-upload")).attach("click", function() { 
      manualUploader.uploadStoredFiles(); 
     }); 
    </script> 
</body> 
</html> 

Вот мой Endpoint.php Файл

require_once "handler.php"; 


$uploader = new UploadHandler(); 

// Specify the list of valid extensions, ex. array("jpeg", "xml", "bmp") 
$uploader->allowedExtensions = array(); // all files types allowed by default 

// Specify max file size in bytes. 
$uploader->sizeLimit = null; 

// Specify the input name set in the javascript. 
$uploader->inputName = "qqfile"; // matches Fine Uploader's default inputName value by default 

// If you want to use the chunking/resume feature, specify the folder to temporarily save parts. 
$uploader->chunksFolder = "chunks"; 

$method = $_SERVER["REQUEST_METHOD"]; 
if ($method == "POST") { 
    header("Content-Type: text/plain"); 

    // Assumes you have a chunking.success.endpoint set to point here with a query parameter of "done". 
    // For example: /myserver/handlers/endpoint.php?done 
    if (isset($_GET["done"])) { 
     $result = $uploader->combineChunks("files"); 
    } 
    // Handles upload requests 
    else { 
     // Call handleUpload() with the name of the folder, relative to PHP's getcwd() 
     $result = $uploader->handleUpload("files"); 

     // To return a name used for uploaded file you can use the following line. 
     $result["uploadName"] = $uploader->getUploadName(); 
    } 

    echo json_encode($result); 
} 
// for delete file requests 
else if ($method == "DELETE") { 
    $result = $uploader->handleDelete("files"); 
    echo json_encode($result); 
} 
else { 
    header("HTTP/1.0 405 Method Not Allowed"); 
} 

?> 

Вот мой файл handler.php, я только с помощью традиционной стороне сервера пример по умолчанию ,

class UploadHandler { 

public $allowedExtensions = array(); 
public $sizeLimit = null; 
public $inputName = 'qqfile'; 
public $chunksFolder = 'chunks'; 

public $chunksCleanupProbability = 0.001; // Once in 1000 requests on avg 
public $chunksExpireIn = 604800; // One week 

protected $uploadName; 

/** 
* Get the original filename 
*/ 
public function getName(){ 
    if (isset($_REQUEST['qqfilename'])) 
     return $_REQUEST['qqfilename']; 

    if (isset($_FILES[$this->inputName])) 
     return $_FILES[$this->inputName]['name']; 
} 

public function getInitialFiles() { 
    $initialFiles = array(); 

    for ($i = 0; $i < 5000; $i++) { 
     array_push($initialFiles, array("name" => "name" + $i, uuid => "uuid" + $i, thumbnailUrl => "")); 
    } 

    return $initialFiles; 
} 

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

public function combineChunks($uploadDirectory, $name = null) { 
    $uuid = $_POST['qquuid']; 
    if ($name === null){ 
     $name = $this->getName(); 
    } 
    $targetFolder = $this->chunksFolder.DIRECTORY_SEPARATOR.$uuid; 
    $totalParts = isset($_REQUEST['qqtotalparts']) ? (int)$_REQUEST['qqtotalparts'] : 1; 

    $targetPath = join(DIRECTORY_SEPARATOR, array($uploadDirectory, $uuid, $name)); 
    $this->uploadName = $name; 

    if (!file_exists($targetPath)){ 
     mkdir(dirname($targetPath), 0777, true); 
    } 
    $target = fopen($targetPath, 'wb'); 

    for ($i=0; $i<$totalParts; $i++){ 
     $chunk = fopen($targetFolder.DIRECTORY_SEPARATOR.$i, "rb"); 
     stream_copy_to_stream($chunk, $target); 
     fclose($chunk); 
    } 

    // Success 
    fclose($target); 

    for ($i=0; $i<$totalParts; $i++){ 
     unlink($targetFolder.DIRECTORY_SEPARATOR.$i); 
    } 

    rmdir($targetFolder); 

    if (!is_null($this->sizeLimit) && filesize($targetPath) > $this->sizeLimit) { 
     unlink($targetPath); 
     http_response_code(413); 
     return array("success" => false, "uuid" => $uuid, "preventRetry" => true); 
    } 

    return array("success" => true, "uuid" => $uuid); 
} 

/** 
* Process the upload. 
* @param string $uploadDirectory Target directory. 
* @param string $name Overwrites the name of the file. 
*/ 
public function handleUpload($uploadDirectory, $name = null){ 

    if (is_writable($this->chunksFolder) && 
     1 == mt_rand(1, 1/$this->chunksCleanupProbability)){ 

     // Run garbage collection 
     $this->cleanupChunks(); 
    } 

    // Check that the max upload size specified in class configuration does not 
    // exceed size allowed by server config 
    if ($this->toBytes(ini_get('post_max_size')) < $this->sizeLimit || 
     $this->toBytes(ini_get('upload_max_filesize')) < $this->sizeLimit){ 
     $neededRequestSize = max(1, $this->sizeLimit/1024/1024) . 'M'; 
     return array('error'=>"Server error. Increase post_max_size and upload_max_filesize to ".$neededRequestSize); 
    } 

    if ($this->isInaccessible($uploadDirectory)){ 
     return array('error' => "Server error. Uploads directory isn't writable"); 
    } 

    $type = $_SERVER['CONTENT_TYPE']; 
    if (isset($_SERVER['HTTP_CONTENT_TYPE'])) { 
     $type = $_SERVER['HTTP_CONTENT_TYPE']; 
    } 

    if(!isset($type)) { 
     return array('error' => "No files were uploaded."); 
    } else if (strpos(strtolower($type), 'multipart/') !== 0){ 
     return array('error' => "Server error. Not a multipart request. Please set forceMultipart to default value (true)."); 
    } 

    // Get size and name 
    $file = $_FILES[$this->inputName]; 
    $size = $file['size']; 
    if (isset($_REQUEST['qqtotalfilesize'])) { 
     $size = $_REQUEST['qqtotalfilesize']; 
    } 

    if ($name === null){ 
     $name = $this->getName(); 
    } 

    // check file error 
    if($file['error']) { 
     return array('error' => 'Upload Error #'.$file['error']); 
    } 

    // Validate name 
    if ($name === null || $name === ''){ 
     return array('error' => 'File name empty.'); 
    } 

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

    if (!is_null($this->sizeLimit) && $size > $this->sizeLimit) { 
     return array('error' => 'File is too large.', 'preventRetry' => true); 
    } 

    // Validate file extension 
    $pathinfo = pathinfo($name); 
    $ext = isset($pathinfo['extension']) ? $pathinfo['extension'] : ''; 

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

    // Save a chunk 
    $totalParts = isset($_REQUEST['qqtotalparts']) ? (int)$_REQUEST['qqtotalparts'] : 1; 

    $uuid = $_REQUEST['qquuid']; 
    if ($totalParts > 1){ 
    # chunked upload 

     $chunksFolder = $this->chunksFolder; 
     $partIndex = (int)$_REQUEST['qqpartindex']; 

     if (!is_writable($chunksFolder) && !is_executable($uploadDirectory)){ 
      return array('error' => "Server error. Chunks directory isn't writable or executable."); 
     } 

     $targetFolder = $this->chunksFolder.DIRECTORY_SEPARATOR.$uuid; 

     if (!file_exists($targetFolder)){ 
      mkdir($targetFolder, 0777, true); 
     } 

     $target = $targetFolder.'/'.$partIndex; 
     $success = move_uploaded_file($_FILES[$this->inputName]['tmp_name'], $target); 

     return array("success" => true, "uuid" => $uuid); 

    } 
    else { 
    # non-chunked upload 

     $target = join(DIRECTORY_SEPARATOR, array($uploadDirectory, $uuid, $name)); 

     if ($target){ 
      $this->uploadName = basename($target); 

      if (!is_dir(dirname($target))){ 
       mkdir(dirname($target), 0777, true); 
      } 
      if (move_uploaded_file($file['tmp_name'], $target)){ 
       return array('success'=> true, "uuid" => $uuid); 
      } 
     } 

     return array('error'=> 'Could not save uploaded file.' . 
      'The upload was cancelled, or server error encountered'); 
    } 
} 

/** 
* Process a delete. 
* @param string $uploadDirectory Target directory. 
* @params string $name Overwrites the name of the file. 
* 
*/ 
public function handleDelete($uploadDirectory, $name=null) 
{ 
    if ($this->isInaccessible($uploadDirectory)) { 
     return array('error' => "Server error. Uploads directory isn't writable" . ((!$this->isWindows()) ? " or executable." : ".")); 
    } 

    $targetFolder = $uploadDirectory; 
    $url = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); 
    $tokens = explode('/', $url); 
    $uuid = $tokens[sizeof($tokens)-1]; 

    $target = join(DIRECTORY_SEPARATOR, array($targetFolder, $uuid)); 

    if (is_dir($target)){ 
     $this->removeDir($target); 
     return array("success" => true, "uuid" => $uuid); 
    } else { 
     return array("success" => false, 
      "error" => "File not found! Unable to delete.".$url, 
      "path" => $uuid 
     ); 
    } 

} 

/** 
* Returns a path to use with this upload. Check that the name does not exist, 
* and appends a suffix otherwise. 
* @param string $uploadDirectory Target directory 
* @param string $filename The name of the file to use. 
*/ 
protected function getUniqueTargetPath($uploadDirectory, $filename) 
{ 
    // Allow only one process at the time to get a unique file name, otherwise 
    // if multiple people would upload a file with the same name at the same time 
    // only the latest would be saved. 

    if (function_exists('sem_acquire')){ 
     $lock = sem_get(ftok(__FILE__, 'u')); 
     sem_acquire($lock); 
    } 

    $pathinfo = pathinfo($filename); 
    $base = $pathinfo['filename']; 
    $ext = isset($pathinfo['extension']) ? $pathinfo['extension'] : ''; 
    $ext = $ext == '' ? $ext : '.' . $ext; 

    $unique = $base; 
    $suffix = 0; 

    // Get unique file name for the file, by appending random suffix. 

    while (file_exists($uploadDirectory . DIRECTORY_SEPARATOR . $unique . $ext)){ 
     $suffix += rand(1, 999); 
     $unique = $base.'-'.$suffix; 
    } 

    $result = $uploadDirectory . DIRECTORY_SEPARATOR . $unique . $ext; 

    // Create an empty target file 
    if (!touch($result)){ 
     // Failed 
     $result = false; 
    } 

    if (function_exists('sem_acquire')){ 
     sem_release($lock); 
    } 

    return $result; 
} 

/** 
* Deletes all file parts in the chunks folder for files uploaded 
* more than chunksExpireIn seconds ago 
*/ 
protected function cleanupChunks(){ 
    foreach (scandir($this->chunksFolder) as $item){ 
     if ($item == "." || $item == "..") 
      continue; 

     $path = $this->chunksFolder.DIRECTORY_SEPARATOR.$item; 

     if (!is_dir($path)) 
      continue; 

     if (time() - filemtime($path) > $this->chunksExpireIn){ 
      $this->removeDir($path); 
     } 
    } 
} 

/** 
* Removes a directory and all files contained inside 
* @param string $dir 
*/ 
protected function removeDir($dir){ 
    foreach (scandir($dir) as $item){ 
     if ($item == "." || $item == "..") 
      continue; 

     if (is_dir($item)){ 
      $this->removeDir($item); 
     } else { 
      unlink(join(DIRECTORY_SEPARATOR, array($dir, $item))); 
     } 

    } 
    rmdir($dir); 
} 

/** 
* Converts a given size with units to bytes. 
* @param string $str 
*/ 
protected 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; 
} 

/** 
* Determines whether a directory can be accessed. 
* 
* is_executable() is not reliable on Windows prior PHP 5.0.0 
* (http://www.php.net/manual/en/function.is-executable.php) 
* The following tests if the current OS is Windows and if so, merely 
* checks if the folder is writable; 
* otherwise, it checks additionally for executable status (like before). 
* 
* @param string $directory The target directory to test access 
*/ 
protected function isInaccessible($directory) { 
    $isWin = $this->isWindows(); 
    $folderInaccessible = ($isWin) ? !is_writable($directory) : (!is_writable($directory) && !is_executable($directory)); 
    return $folderInaccessible; 
} 

/** 
* Determines is the OS is Windows or not 
* 
* @return boolean 
*/ 

protected function isWindows() { 
    $isWin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'); 
    return $isWin; 
} 

}

+0

Просто говоря, «это не работает», недостаточно, чтобы предоставить помощь. Что _специфично_ идет не так? Какие симптомы вы видите? Какие сообщения журнала еще больше освещают проблему? Кроме того, код, который вы здесь включили, является неполным. Где код, который пытается обработать загрузку и объединить куски? –

+0

Мои извинения. Для всех интенсивных целей я в значительной степени нуб с этим, Не понимаю, что я забыл включить мой Handler.php, я отредактировал свой вопрос, чтобы включить его, мой ответ консоли firefox на успешную загруженную загрузку, и попытался сделать мою проблему немного более ясной, пожалуйста, дайте мне знать, как я могу сделать вещи более понятными, и если есть что-то еще, что мне не хватает, это было бы полезно включить. В принципе, я не знаю, как заставить файлы chunked объединиться после успешной загрузки, заставляет меня думать, что я не настраиваю свой кусок. Правильно ли конечная точка успеха. – GrandStar

+0

Похоже, ваши файлы объединены без проблем. –

ответ

0

Спасибо за помощь в убедившись, что мой код был правильным, Выгнали меня в лицо для этого! Поскольку я долгое время думал о неправильной настройке Apache Environment, это стало причиной всех моих проблем.

У меня не было установки .htaccess, которая, казалось, исправила все мои проблемы.

Ниже приведены шаги, которые я предпринял для решения моей проблемы.

Первый шаг

Открыть файл apache.conf в

sudo vim /etc/apache2/apache2.conf 

Второй шаг

удалить комментарий знак (#), если вы найдете его до этой линии (линия номер 187 ок.)

AccessFileName .htaccess 

Третий шаг

Затем найдите строку, в которой есть

<Directory /var/www/> 
    Options Indexes FollowSymLinks 
    AllowOverride None 
    Require all granted 
</Directory> 

замените "None" с "Все"

AllowOverride All 

Шаг Четыре

Activate ModRewrite:

sudo a2enmod rewrite 
sudo service apache2 restart 

Все должно быть хорошо отсюда.