2014-10-06 106 views
3

我使用PHP託管在亞馬遜Elastic Beanstalk上創建我的第一個Web應用程序,我有點在我的腦海中做什麼。我的任務是與AWS S3雲中的最終客戶指定的文件進行聯繫,將其壓縮,最後提供下載鏈接到生成的zip文件。我做了很多狩獵活動以找到我正在嘗試做什麼的實例,但是我對php的缺乏經驗一直在決定某種解決方案是否適合我。從亞馬遜s3使用PHP編碼和下載文件

我發現這個問題和回答here,看到它似乎解決一般意義上的PHP和ZIP下載,我想我可能能夠適應它我的需要。下面是我在PHP中:

<?php 
error_reporting(E_ALL); 
ini_set('display_errors', 1); 

require "./aws.phar"; 
use Aws\S3\S3Client; 

$client = S3Client::factory(array(
    'key' => getenv("AWS_ACCESS_KEY_ID"), 
    'secret' => getenv("AWS_SECRET_KEY") 
)); 

echo "Starting zip test"; 

$client->registerStreamWrapper(); 

// make sure to send all headers first 
// Content-Type is the most important one (probably) 
// 
header('Content-Type: application/octet-stream'); 
header('Content-disposition: attachment; filename="file.zip"'); 

// use popen to execute a unix command pipeline 
// and grab the stdout as a php stream 
// (you can use proc_open instead if you need to 
// control the input of the pipeline too) 
// 
$fp = popen('zip -r - s3://myBucket/test.txt s3://myBucket/img.png', 'r'); 

// pick a bufsize that makes you happy (8192 has been suggested). 
$bufsize = 8192; 
$buff = ''; 
while(!feof($fp)) { 
    $buff = fread($fp, $bufsize); 
    echo $buff; 
} 
pclose($fp); 

這裏是我用來稱呼它:

$(document).ready(function() { 
    $("#download_button").click(function() { 
     $.get("../php/ZipAndDownload.php", function(data){alert(data)}); 
     return false; 
    }); 
}); 

我也試過:

$(document).ready(function() { 
     $("#download_button").click(function() { 
      $.ajax({ 
       url:url, 
       type:"GET", 
       complete: function (response) { 
        $('#output').html(response.responseText); 
       }, 
       error: function() { 
        $('#output').html('Bummer: there was an error!'); 
       } 
      }); 
      return false; 
     }); 
    }); 

現在我每當點擊下載按鈕,我收到「開始zip測試」的回聲,沒有別的。沒有錯誤,也沒有壓縮文件。我需要知道什麼或者我做什麼明顯錯誤?

非常感謝您的幫助和建議。

編輯: 這是我從Derek得到一些建議後的結果。這仍然會產生一個很大的令人討厭的二進制串。

<?php 
header('Content-Type: application/octet-stream'); 
header('Content-disposition: attachment; filename="file.zip"'); 

require "./aws.phar"; 
use Aws\S3\S3Client; 

$bucket = 'myBucket'; 

$client = S3Client::factory(array(
    'key' => getenv('AWS_ACCESS_KEY_ID'), 
    'secret' => getenv('AWS_SECRET_KEY') 
)); 

$result = $client->getObject(array(
    'Bucket' => $bucket, 
    'Key' => 'test.txt', 
    'SaveAs' => '/tmp/test.txt' 
)); 

$Uri = $result['Body']->getUri(); 

$fp = popen('zip -r - '.$Uri, 'r'); 

$bufsize = 8192; 
$buff = ''; 
while(!feof($fp)) { 
    $buff = fread($fp, $bufsize); 
    echo $buff; 
} 
pclose($fp); 
?> 
+2

你正在使用popen,這意味着你正在執行一個外部程序。命令行應用程序將絕對** NO **理解什麼是's3:// etc ...'意味着什麼。他們不處理網址。他們處理文件系統路徑。充其量你可以使用NFS或UNC路徑,如果你在unix/windows上。 – 2014-10-06 20:42:41

回答

4

Marc B的評論是正確的。調用zip不知道s3://的含義。

您需要從S3下載文件,然後在本地壓縮。您有幾種從S3下載文件的選項。例如,你可以使用:

$client->getObjectUrl($bucket, $key) 

獲得一個網址爲您的對象,然後使用捲曲或wget來從URL下載,取決於您的權限設置。

在本地創建文件後,使用保存文件的位置更新zip命令以生成.zip文件。

+0

謝謝你的提示Derek。我已經改變了我的腳本以使用S3的getObject()以及將文件保存在本地存儲中的選項。在本地目錄中引用文件的位置似乎創建了一個我希望的zip包,但是當我回應結果時,我得到一串巨大的二進制表示我的zip文件,而不是提示下載它。我試着將Content-type頭改爲application/zip,但無濟於事。還有什麼我可以錯過? – KDhyne 2014-10-07 17:10:54

+0

您是否在回覆標題('Content-type:...')行之前的任何內容?或者,如果沒有,您的頁面在開始之前是否有<?php之前的任何字符(甚至換行符)?基本上,如果任何字符在標題之前發送,那會導致你描述的內容。 – 2014-10-07 17:50:52

+0

仍然沒有骰子。我已經把我的劇本放到了必需品上,並嘗試了你的建議。我用我目前的內容編輯了我的原文。我能想到的唯一的事情是,也許我用來調用PHP腳本的jQuery是責任?如果沒有什麼你可以看到它的錯誤,但我可能不得不尋找另一種方法。感謝您的幫助。 – KDhyne 2014-10-07 20:51:12