PHP AWS SDK (S3)
使用 PHP AWS SDK (S3) 上传和显示私有文件。
引言
这段代码允许您将文件上传到 Amazon S3,并使其保持私有(也就是说,不能仅通过 S3 URL 简单地查看/下载它们),但可以从您自己的网页中访问它们。
背景
本项目使用了 Donovan Schönknecht 和 Nettuts+ 的想法作为起点。Donovan 编写了一个 S3 PHP 接口,Nettuts+ 使用他的代码来实现上传图像并显示指向上传图像的超链接。
此实现使用 Amazon 提供的 AWS SDK PHP 代码,而不是 Donovan 的代码,并且将文件保持私有,与 Nettuts+ 的实现相反,后者将文件以完全公开访问权限上传到 S3。
Using the Code
提供的源代码包含 AWS SDK PHP(版本 2011.01.14),但您不能简单地解压缩它,将其放在 Web 服务器上并使其运行。假设您已启用 PHP,您仍然需要执行以下操作:
- 拥有一个 Amazon S3 帐户。
- 拥有一个名为“bucket”的存储桶(或者更改代码以查找不同的存储桶)。
- 使用包含的 config-sample.inc.php 创建一个 config.inc.php 文件,其中包含您自己的 S3 凭据(将您的 config.inc.php 文件保存在同一文件夹/目录中)。
到那时,您应该就可以使用了!
代码的第一部分在 index.php 中只是使用表单上传文件。
$s3 = new AmazonS3();
$bucket = "bucket";
// check whether a form was submitted
if (isset($_POST['submit'])) {
// retrieve post variables
$file = $_FILES['file'];
$filename = $file['name'];
$tmpname = $file['tmp_name'];
$contentType = $file['type'];
// upload the file
$fileResource = fopen($tmpname, 'r');
try {
$response = $s3->create_object($bucket, $filename,
array('fileUpload' => $fileResource, 'contentType' => $contentType));
if ($response->isOK())
echo "<strong>Upload of $filename succeeded.</strong>\n";
else
echo "<strong>Upload of $filename failed.</strong>\n";
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
}
}
请注意,我将其放入了 try/catch
块中,因为 S3::create_object()
可能会崩溃(我注意到当我尝试上传几兆字节的文件时,它会这样做)。
index.php 的第二部分显示您在预先指定的存储桶中的文件。它循环遍历存储桶中的文件,并检查该文件是否是图像文件(对文件扩展名的简单检查)。如果是图像,则显示它,否则,它创建一个指向它的超链接,显示一个文档图标。
$response = $s3->list_objects($bucket);
$contents = $response->body->Contents;
foreach ($contents as $content) {
$filename = $content->Key;
echo "<p>$filename</p>\n";
if (isImage($filename)) {
echo "<img width='150' height='100' src='file." +
"php?bucket=$bucket&filename=$filename'/>\n";
} else {
echo "<a href='file.php?bucket=$bucket&filename=$filename'>" +
"<img width='50' height='50' src='document.png'/></a>\n";
}
}
超链接或图像的来源来自 file.php 文件,该文件非常简单明了。
$bucket = $_GET['bucket'];
$filename = $_GET['filename'];
// Include the SDK
require_once 'sdk.class.php';
// Instantiate the class
$s3 = new AmazonS3();
$response = $s3->get_object($bucket, $filename);
$contentType = $response->header['_info']['content_type'];
header("Content-type: $contentType");
header("Content-Disposition: filename=$filename");
echo $response->body;
唯一的“魔术”在于头部指令,它提供了内容类型并在下载时保留文件名。
唯一缺少的是两个文件中更多的防御性代码,以限制其访问。我将把这留给读者作为练习 :-)
关注点
最初,我愚蠢地使用 PHP GD 来使图像显示出来。但是,没有必要这样做。