2015-04-05 227 views
3

我在EC2實例上,並且希望將我的PHP網站與我的Amazon S3存儲桶連接起來,我已經在這裏看到了PHP的API:http://aws.amazon.com/sdkforphp/,但目前還不清楚。如何將上傳的圖像存儲到AWS上的PHP S3

這是代碼行,我需要在我的控制器編輯:

thisFu['original_img']='/uploads/fufu/'.$_POST['cat'].'/original_'.uniqid('fu_').'.jpg'; 

我需要連接到Amazon S3和能夠改變這樣的代碼:

$thisFu['original_img']='my_s3_bucket/uploads/fufu/'.$_POST['cat'].'/original_'.uniqid('fu_').'.jpg'; 

我已經爲此目的配置了一個IAM用戶,但我不知道完成這項工作所需的所有步驟。

如何連接並與Amazon S3進行交互以上載和檢索公共圖像?

UPDATE

我決定用所建議的s3fs嘗試,所以我安裝了它描述here(我的操作系統是Ubuntu的14.04)

我從控制檯運行:

sudo apt-get install build-essential git libfuse-dev libcurl4-openssl-dev libxml2-dev mime-support automake libtool 
sudo apt-get install pkg-config libssl-dev 
git clone https://github.com/s3fs-fuse/s3fs-fuse 
cd s3fs-fuse/ 
./autogen.sh 
./configure --prefix=/usr --with-openssl 
make 
sudo make install 

一切正常安裝,但接下來是什麼?我應該在哪裏聲明證書,以及如何在項目中使用此集成?

月2日更新

我創建了一個與我的IAM憑據accessKeyId:secretAccessKey單一的代碼行稱爲.passwd-s3fs文件。

我把它放到我的home/ubuntu目錄,並把它與控制檯chmod 600 ~/.passwd-s3fs

下一個600允許我跑/usr/bin/s3fs My_S3bucket /uploads/fufu

/uploads/fufu裏面有我現在的所有鬥文件夾。然而,當我試試這個命令:

s3fs -o nonempty allow_other My_S3bucket /uploads/fufu 

我收到此錯誤信息:

s3fs: unable to access MOUNTPOINT My_S3bucket : No such file or directory 

3 UPDATE

至於建議我運行此fusermount -u /uploads/fufu,在那之後我檢查了福福文件夾如預期的那樣是空的。 之後,我再次嘗試此命令(多一個-O):

s3fs -o nonempty -o allow_other My_S3bucket /uploads/fufu 

,並得到該錯誤消息:

fusermount: failed to open /etc/fuse.conf: Permission denied 
fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf 

任何其他建議?

第四UPDATE 18/04/15

在建議從控制檯I運行sudo usermod -a -G fuse ubuntusudo vim /etc/fuse.conf其中I未註釋mount_max = 1000和user_allow_other

比我跑s3fs -o非空-o allow_other My_S3bucket /上傳/ fufu

乍一看沒有錯誤,所以我認爲一切都很好,但它恰恰相反。

現在我有點沮喪,因爲我不知道發生了什麼,但我的文件夾/uploads/fufu被隱藏,使用ls -Al我只看到這個

d????????? ? ?  ?    ?   ? fufu 

我不能sudo rm -r-rfmv -r它說, /uploads/fufu is a directory

我試圖reboot exit and mount -a,但沒有。

我試着用fusermount卸載和錯誤消息是fusermount: entry for /uploads/fufu not found in /etc/mtab

但是我還是須藤的vim的/ etc/mtab中,我發現這條線:s3fs /uploads/fufu fuse.s3fs rw,nosuid,nodev,allow_other 0 0

有人能告訴我我該怎麼卸載最後刪除此文件夾/uploads/fufu

回答

1

儘管「S3fs非常可靠在最近的版本中「,我可以分享我自己的經驗與s3fs和信息,我們移動寫入操作從直接s3fs掛載文件夾訪問aws控制檯(SDK API可能的方式也)定期隨機系統崩潰後。

可能你不會遇到像圖像這樣的小尺寸文件的問題,但是當我們試圖編寫mp4文件時,它肯定會造成問題。因此,在日誌系統崩潰前的最後消息是:

kernel: [ 9180.212990] s3fs[29994]: segfault at 0 ip 000000000042b503 sp 00007f09b4abf530 error 4 in s3fs[400000+52000] 

,這是罕見的隨機的情況下,但自制系統不穩定。

所以我們決定還是繼續s3fs安裝,但只將其用於讀取訪問

下面我展示如何安裝與AIM的憑證s3fs沒有密碼文件

#!/bin/bash -x 
S3_MOUNT_DIR=/media/s3 
CACHE_DIR=/var/cache/s3cache 

wget http://s3fs.googlecode.com/files/s3fs-1.74.tar.gz 
tar xvfz s3fs-1.74.tar.gz 
cd s3fs-1.74 
./configure 
make 
make install 

mkdir $S3_MOUNT_DIR 
mkdir $CACHE_DIR 

chmod 0755 $S3_MOUNT_DIR 
chmod 0755 $CACHE_DIR 

export IAMROLE=`curl http://169.254.169.254/latest/meta-data/iam/security-credentials/` 

/usr/local/bin/s3fs $S3_BUCKET $S3_MOUNT_DIR -o iam_role=$IAMROLE,rw,allow_other,use_cache=$CACHE_DIR,uid=222,gid=500 

你也將需要創建分配給該實例附有政策IAM角色:

{"Statement":[{"Resource":"*","Action":["s3:*"],"Sid":"S3","Effect":"Allow"}],"Version":"2012-10-17"} 

在你的情況下,似乎是合理的使用PHP SDK(對方的回答必須在使用爲例Ë的話),但你也可以寫圖像與AWS控制檯到S3:

aws s3 cp /path_to_image/image.jpg s3://your_bucket/path 

如果你將不得不創建並分配給您的實例,你將不需要提供任何額外的憑證IAM角色

更新 - 回答你的問題:

  • 我不需要包括工廠方法來聲明我的IAM憑證?

是的,如果你將IAM分配到EC2實例,然後在代碼,你只需要創建客戶端爲:

 $s3Client = S3Client::factory(); 
    $bucket = 'my_s3_bucket'; 
    $keyname = $_POST['cat'].'/original_'‌​.uniqid('fu_').'.jpg'; 
    $localFilePath = '/local_path/some_image.jpg'; 

$result = $s3Client->putObject(array(
     'Bucket' => $bucket, 
     'Key' => $keyname, 
     'SourceFile' => $filePath, 
     'ACL' => 'public-read', 
     'ContentType' => 'image/jpeg' 
    )); 
    unlink($localFilePath); 

選項2:如果您不需要文件的本地存儲的階段,但將把direclt從上傳表單:

$s3Client = S3Client::factory(); 
$bucket = 'my_s3_bucket'; 
$keyname = $_POST['cat'].'/original_'‌​.uniqid('fu_').'.jpg'; 
$dataFromFile = file_get_contents($_FILES['uploadedfile']['tmp_name']); 

$result = $s3Client->putObject(array(
    'Bucket' => $bucket, 
    'Key' => $keyname, 
    'Body' => $dataFromFile, 
    'ACL' => 'public-read', 
)); 

而獲得S3鏈接,如果你將有公共訪問

$publicUrl = $s3Client->getObjectUrl($bucket, $keyname); 

或生成標識的URL私人內容

$validTime = '+10 minutes'; 
$signedUrl = $s3Client->getObjectUrl($bucket, $keyname, $validTime); 
+0

感謝您的建議...我喜歡使用PHP SDK但不知道如何,你是否說我不需要包括工廠方法來聲明我的IAM憑證?是否有可能爲桶url創建一個變量並使用它:'my_s3_bucket ='http:// link/to/my/s3'然後'$ thisFu ['original_img'] ='my_s3_bucket/uploads/fufu/'。$ _ POST ['cat']。'/ original _'。uniqid('fu _')。'。jpg';'? – NineCattoRules 2015-04-18 09:08:35

+0

對不起,但我沒有收到有關新更新的通知。哇,謝謝你的詳細的解釋,這似乎很容易...相反,幾天前我用s3fs嘗試過,現在我的上傳文件夾被隱藏,無法以任何方式訪問(你可以閱讀我上面的第4次更新)。我想嘗試這種方法,但直到我有我的上傳文件夾的問題,我甚至不能嘗試。 – NineCattoRules 2015-04-19 10:07:48

+1

我想如果我只是編輯帖子然後通知不會來......我很高興這個信息對你有用:)關於你的問題在更新4:我有點失去了什麼你的問題?禁用s3fs?爲什麼你不能只是來源文件夾,並使:「sudo使卸載」?順便說一句我看到你提到了一些權限問題,你是否從根或sudo命令? – 2015-04-19 10:28:44

1

我同意該鏈接的文檔有點難以挖掘,並留下很多點連接。

然而,我發現更好的東西在這裏很多:http://docs.aws.amazon.com/aws-sdk-php/v2/guide/service-s3.html

它具有示例代碼和指令幾乎所有的S3操作。

+0

嗨,連接後,我怎麼會自動上傳到桶的圖片,用戶上傳?我的代碼如下所示:'$ this ['original_img'] ='/ uploads/img /'.$_ POST ['cat']。'/ original _'。uniqid('my _')。'。jpg';'謝謝 – NineCattoRules 2015-04-05 14:36:25

+0

@Simone你見過那個頁面上的「上傳文件」部分嗎? – 2015-04-05 14:43:58

+0

@Simone你的意思是不斷使用的網址?您可以指定函數的選項來使文件成爲公共或私有。 – 2015-04-05 15:12:23

1

爲了給你一點更清晰,因爲你是一個初學者:使用此位

use Aws\S3\S3Client; 

$client = S3Client::factory(array('profile' => '<profile in your aws credentials file>' 
)); 

通過這個Installation Guide

然後設置您的AWS賬戶的客戶在你的PHP Web服務器下載AWS SDK如果您想了解如何使用AWS證書文件的詳細信息,head here.

然後上傳,你有你自己的PHP服務器上的文件:

$result = $client->putObject(array(
'Bucket'  => $bucket, 
'Key'  => 'data_from_file.txt', 
'SourceFile' => $pathToFile, 
'Metadata' => array(
    'Foo' => 'abc', 
    'Baz' => '123' 
) 
)); 

如果您有興趣學習如何將圖片上傳到php文件,我建議您看看this W3 schools tutorial.本教程可以幫助您在服務器上本地保存文件的臨時目錄上傳到您的S3存儲桶。

+0

終於有人了!感謝您的回覆,但是我無法安裝這樣的東西,確實我在亞馬遜EC2上......手動操作很困難嗎?我認爲足夠把所有文件夾放在根目錄:) – NineCattoRules 2015-04-15 21:56:36

+1

在安裝SDK的第一個鏈接中,轉到從zip指令安裝,而不是使用Aws \ S3 \ S3Client這一行;'require'/ path /to/aws-autoloader.php';' – Erik 2015-04-15 21:59:22

+0

這很明顯,但我應該放到我的項目中?我有我自己的框架,我把它放在根文件夾?或管理文件夾也許?有什麼區別如果有的話 – NineCattoRules 2015-04-15 22:24:51

1

一個更容易的和透明的應用程序安裝很簡單,就是安裝與s3fs

https://github.com/s3fs-fuse/s3fs-fuse

(使用選項allow_other) 你s3fs S3的分區,然後就像一個普通文件夾只會移動文件到該文件夾​​。 S3fs然後上傳

S3fs是近年來非常可靠的建立

可以讀取圖像這樣還可以,但失去了AWS CDN有任何影響,但我最後一次嘗試它,它不是一個巨大的差異

你需要一個s3fspassword文件

格式 accessKeyId:secretAccessKey

它可以在任何這些地方的

using the passwd_file command line option 
setting the AWSACCESSKEYID and AWSSECRETACCESSKEY environment variables 
using a .passwd-s3fs file in your home directory 
using the system-wide /etc/passwd-s3fs file 

該文件需要600個權限

https://github.com/s3fs-fuse/s3fs-fuse/wiki/Fuse-Over-Amazon

有一些信息。

當是完整的命令是s3fs bucket_name mnt_dir

,你可以找到這裏的例子

https://console.aws.amazon.com/iam/home?#security_credential

鍵約我會假設你mnt_dir/uploads/fufu

所以s3fs bucket /uploads/fufu

給你r第二問題

s3fs -o nonempty allow_other My_S3bucket /uploads/fufu 

是錯誤的,你需要指定-o再次

s3fs -o nonempty -o allow_other My_S3bucket /uploads/fufu 

正在安裝的需求,用戶是熔斷器組

sudo usermod -a -G fuse your_user 

或 須藤ADDGROUP在your_user保險絲

+0

謝謝,基本上使用這種方式我不能使用Cloudfront作爲CDN?我激活了Cloudfront併爲原始位置放了我的存儲桶 – NineCattoRules 2015-04-17 09:52:25

+1

如果您所做的唯一更改是使用s3fs,那麼您可以使用s3fs將圖像寫入s3,然後使用帶有API的Cloudfront鏈接。但是需要更改代碼 – exussum 2015-04-17 10:10:01

+0

我更新了我的問題,請檢查一下嗎? – NineCattoRules 2015-04-17 10:21:33