你好,游客 登录
背景:
阅读新闻

使用 PHP 向 Amazon 分载多媒体内容和带宽

[日期:2009-02-25] 来源:ibm   作者:Jack D. Herrington [字体: ]

Web 2.0 的出现带来了 Web 上多媒体的普及。Flikr 刚刚推出几个星期,就有几百万张图片得到了它的服务。Web 1.0 邮票大小的视频也已经被 Google Video 或 YouTube 上浏览器大小的电影所取代。但是,这会让小型 PHP 应用程序的开发人员如何适从呢?当您想要承载大量的图像和巨大的视频文件时会出现什么情况?您那个只需支付 9 美元的托管帐号能提供所有必需的空间和带宽么?为您提供托管服务的公司的 Internet 连接能满足通信流量要求么?可能不行。

  幸运的是,Amazon 找到了补救的方法,就是利用一种全新的客户级 Web 服务:远程存储。只需花费很少费用,您就可以在 Amazon 上托管和存储数十亿字节任何类型的数据。您可将该空间用来存储站点的图像,也可使用 Amazon 保存备份。

  在本文中,我将通过一组 PHP 页面来使用 Amazon S3 托管多媒体文件。尽管还不尽完善,但 Amazon 还是通过提供几个上传和检索内容的方法大大简化了该流程。

  关于 Amazon S3 的更多信息

  使用 Amazon S3 存储服务比较容易。从 Amazon Web Services (AWS) 开始,选择想要的存储服务,并单击 Subscribe。在那儿设置付费机制 —— 通常使用信用卡 —— 也可以使用您用来在 Amazon 上购买书或 DVD 的卡。每上传或下载十亿字节的数据,Amazon 就会给您的卡记一次帐。设置完存储以后,您将会收到一封电子邮件,里面含有一个链接,通过该链接可以获得您的帐户 ID 和密钥。

  有两个关键的概念您必须理解:桶(bucket)和对象。一个桶 就像硬盘上的一个目录。一个对象 就是一个桶中的一个指定的数据块。可在其中存放任何您喜欢的东西,这也正是 Amazon 使用对象 而不使用文件 的原因。对于本例来说,我将上传图像文件到 Amazon S3,因此,每个对象就相当于一个文件。

Amazon S3 支持使用多种方法创建、编辑和删除桶以及其中的对象。如果偏好 SOAP,您可以使用它。或者,如这里的例子中那样,采用 Representational State Transfer (REST) 协议,使用 curl 命令行工具将 GET、PUT 和 DELETE 命令通过 HTTP 发送到 Amazon S3 服务器。PUT 命令创建桶或对象,DELETE 删除桶或对象,GET 检索有关桶或来自对象的数据的信息

  对象可拥有几个级别的访问控制。就我们的目的而言,其中的两种需要特别关注:私有(只有桶的拥有者才能读取其内容)和公有可读(任何人都可以读取但不能修改其内容)。我将使用公有可读选项,以便使用 Amazon S3 来提供图像。图像的 URL 的格式为:http://[bucketname].s3.amazonaws.com/[object] 或 http://s3.amazonaws.com/[bucketname]/[object] 。在我这个图像上传应用程序例子中,一个上传图像的 URL 将类似于:http://jherr_photos.s3.amazonaws.com/IMG_2912.jpg,这种格式十分清晰易读。

  示例应用程序

  我将要创建的应用程序比较简单。我会建一个页面,其中有用来接受文件的表单。然后将该页面提交到一个上传页面,上传页面将一个内容为图像的新对象添加到 Amazon S3 的桶中。此概念如图 1 所示。

  图 1. 上传图像到 Amazon S3

使用 PHP 向 Amazon 分载多媒体内容和带宽

  事实上,该脚本实际并不关心我上传的是什么内容。它只是将文件的内容 —— 以及从上载文件中获取的关联 MIME 类型 ——发送到 Amazon S3。因此我可以上传电影或任何我喜欢的东西。

  当我在 Amazon S3 上存有一些图像时,另一个页面将展示桶的内容。此概念如图 2 所示。

图 2. 图像页面的数据流

使用 PHP 向 Amazon 分载多媒体内容和带宽

  要记住的重要一点是,HTML 页面数据来自我的服务器,但图像数据来自 Amazon S3。是的,我需要向 Amazon 支付带宽费用。但我也同时获得了 Amazon 大量的数据管道、数据中心冗余和它所有的基础设施,而这些是 PHP 托管服务所不能提供的。因此对于大型数据文件,比如电影类型的图像,承载数据的服务器的可靠性以及 Internet 管道的大小就显得非常重要。

  上传页面

  创建这个应用程序的第一步是设置一个 Amazon S3 帐号。在那之后,所要做的就是获取一些用来连接到 Amazon S3 服务的 PHP 代码。不幸的是,当前不论是 Amazon 还是 PEAR 都没有提供针对 PHP 的 Amazon S3 类。因此,我四处搜寻,终于从 Geoff Gaudreault 找到了能够处理所有基础功能的一个 Amazon S3 类。该源代码由于太长的缘故没有被作为清单包含在此,但它在 下载 部分可找到。

  Gaudreault 的这个 Amazon S3 类需要您安装 PEAR 的 Crypt_HMAC 模块,因此第三步是使用以下命令安装该模块:

% pear install Crypt_HMAC

  完成该操作后,编辑 Gaudreault 的 s3.class.php 文件,将 AWS key 和密钥包含进去。密钥用来加密请求的某些部分,以使 Amazon 能够确保是您编写的代码在向他们发送请求。因为是付费服务,最好不要将密钥给任何人。

  要开始实现,您需要一个带有表单的页面来进行文件上传。

  清单 1. Index.php

<html>
<body>
<form enctype="multipart/form-data" action="upload.php" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="2000000" />
<input type="file" name="file" />
<input type="submit" value="Upload" />
</form>
</body>
</html>

上传页面显示在浏览器中。

  图 3. 上传页面

使用 PHP 向 Amazon 分载多媒体内容和带宽

  index.php 脚本将文件提交到一个上传页面。

  清单 2. Upload.php

<?php
require( "s3.class.php" );
$srvc = new S3();
$srvc->putBucket( 'jherr_photos' );
$tmpfile = 'tmpfile';
move_uploaded_file( $_FILES['file']['tmp_name'], $tmpfile );
chmod( $tmpfile, 0777 );
$fh = fopen( $tmpfile, 'rb' );
$contents = fread( $fh, filesize( $tmpfile ) );
fclose( $fh );
$srvc->putObject( $_FILES['file']['name'], $contents,
 'jherr_photos', 'public-read',
 $_FILES['file']['type'] );
unlink( $tmpfile );
?>

  首先,包含 Amazon S3 PHP 库。然后创建一个 Amazon S3 对象并构建包含对象的桶。Amazon S3 足够友好,如果已存在一个桶,它将完全忽视构建另一个桶的请求。因此在第一次运行此代码后,桶的创建请求将被忽视。

  创建桶后,将上传文件移动到一个您可以阅读它并更改其权限的位置以便获取其内容。然后将整个文件读取到 $contents 变量中。此后,使用 S3 对象将文件添加到桶中。如果同名文件已存在,则该文件的内容会被完全取代。在此脚本的最后,删除临时的上传文件。

  检索图像

  下一步是在 Web 页面上实际查看上传图像。要完成此操作,必须构建另一个称作 list.php 的 PHP 脚本。

清单 3. List.php

<?php
require( "s3.class.php" );
$srvc = new S3();
$resp = $srvc->getBucket( 'jherr_photos' );
preg_match_all( "/<Key>(.*?)</Key>/", $resp, $found );
?>
<html><body><table>
<?php foreach( $found[1] as $key ) { ?>
<tr><td>
<img
src="http://jherr_photos.s3.amazonaws.com/<?php echo($key) ?>" />
</td></tr><?php } ?>
</table></body></html>

  该脚本首先包含库和创建 S3 对象。然后使用 getBucket() 方法来获取桶的当前内容。该信息作为包含 XML 代码的一个字符串返回。XML 代码中有很多内容,但最重要的是文件名,它们被存储在 <Key> 标记中。可以使用 XML 解析器读出 <Key> 标记,但在本例中使用一个正则表达式会更为容易。

  有了所找到的 <Key> 标记的数组后,创建一张表,表中每一行都有单一一个图像标记,该标记使用源中的文件名。要测试此过程,我上传了几张我和我家人的圣诞照片,然后转到 list.php 页面。结果如下所示。

  图 4. 带有来自 Amazon S3 的照片的列表页面

使用 PHP 向 Amazon 分载多媒体内容和带宽

  我将之看作是 Amazon S3 样例的 HelloWorld 版。它要多简单有多简单。虽然我可以使用命令行脚本,但在浏览器中查看它更有意思。从本例您可以看到使用 Amazon S3 是多么容易。

缺陷

  本例表面上看起来很简单,实际上 S3 类中包含了大量的复杂处理。大多数 Web 请求相对简单,问题一般都出在请求的签名部分。Amazon 需要使用一个只有您知道的密钥对每个请求进行签名。而该签名过程十分不易处理,也很难调试。所幸的是,S3 类隐藏了这些复杂性。

  手边有了 S3 类,签名过程就不是问题了。但如果真遇到了问题,为了解决它,您常常需要系统地查阅文档和使用 Amazon 签名工具的帮助,这可能会花费您一两个小时的时间。在那之后,使用 Amazon S3 服务及其姊妹服务 —— Amazon Simple Queue Service (SQS) —— 就容易了。

  Amazon S3 的世界

  Amazon S3 只是位于一个更大的上下文中的一组服务之一。其他两个与 Amazon S3 特别相关的服务是 Amazon SQS 及 Amazon Elastic Compute Cloud (EC2)。

  Amazon SQS 可以通过指定队列让应用程序得以相互通信,在该队列中,应用程序根据各种事件(例如,“添加一个用户”、“请求报告”)插入消息,其他应用程序读取并处理那些消息,然后将其从队列中删除。此功能与 TIBCO 提供的服务类似,可用于允许企业应用程序以一种松散方式进行耦合。

  Amazon EC2 服务,在写作本文时还处于测试阶段,它允许以一种随需应变的方式使用 Amazon 服务器池的计算功能。您可以创建应用程序的一个 Amazon 机器镜像(Amazon Machine Image),然后将该镜像上传到 Amazon S3。之后向 Amazon EC2 服务发出启动流程、停止流程和监控流程的请求。如果您已经编写应用程序来利用此功能的话,定会惊讶于它所提供的强大的随需应变的处理能力。

  如果将所有三种服务看作一个包 —— 将 Amazon S3 用作磁盘、将 Amazon SQS 用作消息底板,将 Amazon EC2 用作过程管理系统,那么 Amazon 想要做什么就很清楚了。Amazon 想要成为为小型和中型业务提供随需应变的计算能力的供应商。到那时,从 Amazon EC2 系统使用 Amazon S3 将会免费。

  结束语

  Amazon S3 除了分载站点的一部分带宽以外,还可用来做其他很多事情,比如:

  备份 使用 Amazon S3 存储数据库的夜间备份。Amazon 的 S3Curl 命令行脚本可很容易地用来进行此类处理。 共享存储 您不再需要使用 USB 驱动器,而是可以创建一个 Amazon S3 文件夹,然后使用工具,比如 Jungle Disk(它将 Amazon S3 像硬盘一样挂载),创建文件的共享存储库。之后,您就可在自己的计算机间或自己与组员之间使用此存储库。您甚至可在自己与远程 Web 服务器之间使用它。 小型 Web 站点 通过将 HTML 和图像上传到 Amazon S3,您只需花很少费用就可在 Amazon S3 上托管静态的小型 Web 站点。 播客、视频博客或图像博客 使用 Amazon S3,可上传播客媒体文件及 RSS V2.0 XML 并可直接在 Amazon S3 上运行播客。

  越使用 Amazon S3,我就越喜欢它。界面简单,系统可靠。更好的是,价格可以承受。尝试一下 Amazon S3 看看是否可在自己的 Web 应用程序中使用它。

推荐 打印 | 录入: | 阅读:
相关新闻      
本文评论   
评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款