2016-11-06 7 views
1

チャンクドのアップロードは、私が取り組んでいるプロジェクトでうまくいくようにしてきました。すべての集中的な目的のために、自分自身を教えている完全なnoobと、ウェブサイトから手動アップロードテンプレートを使用しています。また、従来のサーバーサイドのサンプルファイルを使用して、コードの仕組みを理解し、私が構築する完全に機能的な例にしてください。私はほとんどのものを動かすことができました。ファインアップローダーでファイルをアップロードするとアップロード成功後にチャンクを結合/マージできない

チャンクを使わずにファイルをアップロードすると、正常にファイルをアップロードすることができました。ただし、チャンクを使用すると、ファイルをチャンクしてフォルダを私のチャンクディレクトリに置くことはできませんが、チャンクをまとめて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のよ言ったように。どんな助けも大いに感謝しています。

ここに私のアップローダーコードボディ

ここ
<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

単に「機能しません」と言っても、ヘルプを提供するには不十分です。 _specifically_何が間違っていますか?どのような症状が見られますか?どのようなログメッセージがさらに問題を照らしていますか?さらに、ここに含まれているコードは不完全です。アップロードを処理し、チャンクを結合しようとするコードはどこにありますか? –

+0

私の謝罪は、すべての集中的な目的のために私はこれでかなりノブです、私は私のHandler.phpを含めることを忘れていた、私はそれを含めるために私の質問を編集した、成功したチャンクアップロードで私のfirefoxコンソール応答、私の問題を少しはっきりさせようとしましたが、物事を理解しやすくする方法を教えてください。もし私が欠けているものがあれば、それを含めると有益でしょう。基本的には、正常にアップロードされた後にチャンクファイルを一緒にマージする方法がわからないので、チャンクを正しくセットアップしていないと思うようにします。 – GrandStar

+0

ファイルが問題なく結合されているようです。 –

答えて

0

私のコードが正しかったことを確認することで助けてくれてありがとうは、このいずれかの顔に自分自身を蹴りました!最長の時間を考えていたので、誤って設定されたApache環境がすべての私の問題の根源でした。

私はすべての問題を修正するような.htaccess setupを持っていませんでした。

ここでは、問題を解決するための手順を示します。

sudo vim /etc/apache2/apache2.conf 

第二ステップとして

まずステップ

オープンapache.confファイルを使用すると、この行(行番号187程度前にそれを見つけた場合

削除コメント記号(#)。)

AccessFileName .htaccess 

第三工程

その後

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

は "すべて"

AllowOverride All 

四ステップ

アクティブで "None" を交換しないでそこにある行を見つけますModRewrite:

sudo a2enmod rewrite 
sudo service apache2 restart 

ここからすべてが良いはずです。

関連する問題