2015-04-05 229 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