2016-12-30 50 views
10

我正在使用official PHP SDKthe official service provider for laravel將圖像上傳到Amazon S3。圖像暫時存儲在我的服務器上,上傳後應該刪除。以下是我用來上傳和刪除的代碼。如何在AWS S3 Helper上傳文件後解鎖文件?

$temp_path = "/screenshot_temp/testing.png"; 

$client = AWS::createClient('s3'); 
$result = $client->putObject(array(
     'Bucket'  => self::$bucketName, 
     'Key'  => 'screenshot/testing.png', 
     'SourceFile' => $temp_path, 
     'ACL' => 'public-read' 
    )); 
); 

chown($temp_path, 777); 
unlink($temp_path); 

上傳成功。我可以通過鏈接返回來看到我的圖像,並且我可以在亞馬遜控制檯上看到它。問題是,刪除失敗,並出現以下錯誤信息:

ErrorException: unlink(... path of my file ...): Permission denied 

我相信我的文件權限設置是正確的,我可以刪除我的文件,部分代碼上傳到S3註釋掉。所以應該是在上傳文件時文件被鎖定的問題。有沒有辦法解鎖和刪除我的文件?

+0

桶對象不是文件 – 2016-12-30 11:27:21

回答

6

是流上傳鎖住,直到它完成,試試下面的2文件,

$client = AWS::createClient('s3'); 
$fileContent = file_get_contents($temp_path); 
$result = $client->putObject(array(
    'Bucket'  => self::$bucketName, 
    'Key'  => 'screenshot/testing.png', 
    'Body'  => $fileContent, 
    'ACL'  => 'public-read' 
)); 
); 

unlink($temp_path); 

$client = AWS::createClient('s3'); 
$fileContent = file_get_contents($temp_path); 
$result = $client->putObject(array(
    'Bucket'  => self::$bucketName, 
    'Key'  => 'screenshot/testing.png', 
    'Body'  => $fileContent, 
    'ACL'  => 'public-read' 
)); 
); 

gc_collect_cycles(); 
unlink($temp_path); 
+0

首先,我猜它應該是'file_get_contents()',否則會導致找不到函數。即使我更改爲file_get_contents,代碼也不起作用。該函數仍然以'$ fileContent'作爲文件路徑並返回文件未找到。 – cytsunny

+0

我的壞,:(更正了我的代碼 – Vineesh

+0

不知道第二種方法,但第一種方法適用於我 – cytsunny

1

編輯:我只注意到在$ temp_path的字符串開頭帶有「 /「斜槓字符。這個開始的斜槓通常從網站的根目錄開始,你確定這是正確的位置嗎?在PHP中使用getcwd()命令來找出PHP認爲它在哪裏的文件夾。

我明白你相信權限是正確的,但鑑於「權限被拒絕」的錯誤,我仍然相信它告訴你一些相關的東西。

我看你是試圖chown目錄,你可能是想chmod它嗎?如果你能ssh到你的服務器,並運行此命令,你可能有更多的運氣:

chmod -R 777 /(your-website-dir/screenshot_temp 

甚至嘗試「chown」將「文件模式」在你的PHP代碼改變。

+0

這是一個用於演示目的的虛假位置出於安全原因,我不會發布實際路徑。路徑不在根目錄下,我確信上傳成功的路徑是正確的。 – cytsunny

+0

好了,但你有沒有嘗試用chmod? – Seb

+0

替換錯誤的chown命令,我相信它也是正確的,因爲當我使用'ls'命令時,我可以看到權限被改變了 – cytsunny

3

當您使用SourceFile選項時putObject S3Client打開一個文件,但在操作後不會關閉它。

在大多數情況下,您只需取消設置$client和/或$result即可關閉打開的文件。 但是不幸的是不是這種情況。

使用Body選項而不是SourceFile

// temp file 
$file = fopen($temp_path, "r"); 

// use resource, not a path 
$result = $client->putObject(array(
     'Bucket'  => self::$bucketName, 
     'Key'  => 'screenshot/testing.png', 
     'Body'  => $file, 
     'ACL'  => 'public-read' 
    )); 
); 

fclose($file); 

unlink($temp_path); 
1

我不是一個PHP的傢伙,但我會嘗試將該壞男孩彈入流中,然後將該流傳遞給SDK。

這樣,您可以顯式關閉流,然後刪除臨時文件。如果您的具體使用情況允許,您甚至可以完全刪除臨時文件並僅處理流。

看起來像this SO post可能會將您置於正確的軌道上。

+0

是的,這就是其他答案的建議。我驚訝地發現由亞馬遜編寫的SDK沒有提供關閉流的方法,或者只是關閉默認流..... – cytsunny