В первой части этой серии статей Джефф показал нам, как начать программировать сервис хранения S3 в Amazon. Если вы следовали этому руководству, вы настроили свою учетную запись AWS, загрузили библиотеку CloudFusion и настроили ее с помощью ключей аутентификации. Вы также видели несколько простых способов создания блоков и получения списков блоков из вашего PHP-кода.
На этой неделе мы пойдем дальше: покажем, как загружать файлы в S3, создавать простой сервис хранения миниатюр и распространять свои файлы с помощью CloudFront CDN.
Обе эти статьи были взяты из последнего выпуска книги SitePoint, «Разместите ваш веб-сайт в облаке», «Amazon Web Services Made Easy» . Они оба были взяты из главы 4, которая также доступна как часть бесплатного образца книги в формате PDF .
Я предполагаю, что вы уже проработали первую часть . Теперь, когда вы знаете, как создавать сегменты и перечислять их на веб-странице, пришло время поговорить об основной функции Amazon S3: хранении файлов. Но прежде чем мы это сделаем, пришло время сделать небольшой обход.
Программы в этой статье, начинающиеся с символа shebang ( #!/usr/bin/php
), должны запускаться из командной строки. Другие предназначены для запуска через веб-сервер.
Все функции CloudFusion, о которых я вам рассказал, возвращают простые структуры данных — массивы строк. Однако функции, которые я буду использовать позже в этой статье, возвращают более сложную структуру данных, называемую ResponseCore
. S3 возвращает свои результаты в виде XML-документа; CloudFusion анализирует XML с помощью пакета PHP SimpleXML и включает проанализированные объекты в ответ, где на них можно ссылаться по имени. [ 1 ]
Со времени, когда мы опубликовали книгу и первую статью в этой серии, библиотека CloudFusion стала официальным AWS SDK для PHP . Этот выпуск поставляется с улучшенной поддержкой регионов AWS, а также с множеством других улучшений. Это может означать, что вам нужно будет внести некоторые небольшие изменения в код, если вы не используете версию 2.5 библиотеки , но, поскольку новый SDK 1.0 полностью основан на старой кодовой базе CloudFusion, эти изменения должны быть незначительными, и мало и далеко друг от друга.
Следующий код вызывает S3 для отображения первых 1000 объектов в BOOK_BUCKET
, а затем вызывает print_r
функцию PHP print_r
для отображения результирующего дерева объектов:
Пример 1. chapter_04/list_bucket_objects_raw.php
(отрывок)
#! / usr / bin / php <? phperror_reporting (E_ALL); require_once ('cloudfusion.class.php'); require_once ('include / book.inc.php'); $ s3 = new AmazonS3 (); $ res = $ s3-> list_objects (BOOK_BUCKET); print_r ($ Рез), выход (0);?>
Результирующий вывод слишком длинный, чтобы отобразить его целиком (465 строк для моих сегментов). Давайте посмотрим на некоторые выдержки вместо этого. Вот первая часть:
$
php list_bucket_objects_raw.php
ResponseCore Object[header] => Array( [x-amz-id-2] => Ya7yAuUClv7HgR6+JJpz0sYDM1m4/Zy+d0Rmk5cSAu+qV+v+6➥9gLSHlytlD77wAn [x-amz-request-id] => 14AA13F3F0B76032 [date] => Thu, 28 May 2009 06:51:26 GMT [content-type] => application/xml [transfer-encoding] => chunked [connection] => close [server] => AmazonS3 [_info] => Array ( https%3A%2F%2Fwww.sitepoint.com => https://sitepoint-aws-cloud-book.s3.amazonaws.com/ [content_type] => application/xml ⋮
Первая строка указывает, что данные имеют тип ResponseCore
. Далее мы найдем несколько стандартных массивов PHP. Если нам нужно, мы можем получить доступ к данным следующим образом:
$ Res-> заголовок [ 'Transfer-Encoding'] $ res-> заголовок [ '_ Информация о'] [ 'URL']
$res
является объектом, а header
является одной из переменных экземпляра объекта, поэтому доступ к нему осуществляется с помощью оператора ->
. Переменная экземпляра header
является массивом PHP, поэтому доступ к ее членам осуществляется с использованием синтаксиса массива.
Во второй строке член _info
header
сам по себе является массивом, поэтому второй набор скобок используется для доступа к значению url
внутри.
Чуть дальше в выводе мы находим следующее:
[body] => SimpleXMLElement Object( [Name] => sitepoint-aws-cloud-book ⋮
Переменная экземпляра body
имеет тип SimpleXMLElement
. Он начинается с переменной экземпляра Name
, к которой можно получить доступ как $res->body->Name
.
Еще дальше мы наконец-то нашли то, для чего мы пришли — список объектов в корзине:
[Contents] => Array( [0] => SimpleXMLElement Object ( [Key] => images/2008_shiller_housing_projection.jpg [LastModified] => 2009-05-22T23:44:58.000Z [ETag] => "e2d335683226059e7cd6e450795f3485" [Size] => 236535 [Owner] => SimpleXMLElement Object ( [ID] => 7769a42be4e57a034eeb322aa8450b3536b6ca56037c06ef19b1e1➥eabfeaab9c [DisplayName] => jeffbarr ) [StorageClass] => STANDARD ) ⋮
Вы можете видеть, что body
содержит переменную экземпляра с именем Contents
, которая является другим массивом, содержащим все файлы в корзине. Каждый файл в SimpleXMLElement
объектом SimpleXMLElement
; у каждого есть ETag
Key
, ETag
, Size
, Owner
и StorageClass
, доступ к которым осуществляется следующим образом:
$ Res-> Автодиагностика> Содержание [0] -> Основные $ res-> Автодиагностика> Содержание [0] -> ETag $ res-> Автодиагностика> Содержание [0] -> Размер $ res-> Автодиагностика> Содержание [0] -> Owner-> ID $ res-> Автодиагностика> Содержание [0] -> Owner-> отображаемое_имя $ res-> Автодиагностика> Содержание [0] -> Класс складирования
Конечно, вы можете использовать промежуточные переменные, чтобы сделать этот код короче или эффективнее.
Вам может быть интересно, откуда берутся названия объектов ( Contents
, Key
, Size
и т. Д.). Метод list_objects
делает HTTP- GET
к S3, чтобы получить список первых 1000 объектов в корзине. Запрос возвращает XML-документ, а CloudFusion анализирует и возвращает его как объект body
. Имена объектов берутся непосредственно из тегов XML в документе.
Если бы мы изменили предыдущий скрипт, чтобы распечатать некоторые из этих значений, он может выглядеть следующим образом:
#! / usr / bin / php <? phperror_reporting (E_ALL); require_once ('cloudfusion.class.php'); require_once ('include / book.inc.php'); $ s3 = new AmazonS3 (); $ res = $ s3-> list_objects (BOOK_BUCKET); print ("Bucket Url:". $ res-> header ['_ info'] ['url']. "n"); print ("Bucket Name:". $ res-> body-> Name. "n") ; print ("Первый ключ:". $ res-> body-> Contents [0] -> Key. "n"); print ("Второй ключ:". $ res-> body-> Contents [1] -> Ключ. "N"); Выход (0);?>
В приведенном выше примере мы выводим URL и имя корзины, а затем ключи первых двух элементов в корзине.
Теперь мы подошли к концу объезда. Я надеюсь, что поездка была сценической, все же образовательной. Далее мы будем использовать эти новые знания для создания очень удобной функции полезности.
Прежде чем мы сможем написать скрипт, который выводит список всех объектов в корзине на веб-странице, мы сначала должны написать довольно сложную функцию. Мы добавим эту функцию в наш файл book.inc.php
и назовем ее getBucketObjects
:
Пример 2. chapter_04/include/book.inc.php
(отрывок)
функция getBucketObjects ($ s3, $ bucket, $ prefix = '') {$ objects = array (); $ next = ''; делать {$ res = $ s3-> list_objects ($ bucket, array ('marker' => urlencode ($ next), 'prefix' => $ prefix)); if (! $ res-> isOK ()) {вернуть ноль; } $ contents = $ res-> body-> Contents; foreach ($ content как $ object) {$ objects [] = $ object; } $ isTruncated = $ res-> body-> IsTruncated == 'true'; if ($ isTruncated) {$ next = $ objects [count ($ objects) - 1] -> Key; }} while ($ isTruncated); вернуть $ объекты; }
Эта функция более сложна, чем все, что вы видели до сих пор, но вам не о чем беспокоиться. Ранее я говорил вам, что один запрос «списка сегментов» к S3 вернет самое большее 1000 ключей, независимо от того, сколько ключей находится в сегменте. Наша функция getBucketObjects
просто снова и снова вызывает list_objects
пока S3 не скажет, что больше нет объектов для возврата:
Наша функция принимает три аргумента: объект |
|
Мы используем цикл |
|
Каждый раз, когда я вызываю |
|
Если вызов |
|
Мы извлекаем массив |
|
Данные, возвращаемые вызовом |
|
Если список неполон, мы устанавливаем значение |
|
Когда цикл завершается, возвращается массив |
Поместите его вместе, и эта функция извлекает все объекты из корзины, помещает их все в один массив и возвращает массив.
Я свободно признаю, что мне не удалось правильно сформулировать условие завершения, когда я впервые написал этот код. Я знал, что это будет сложно, поэтому я использовал оператор print вверху, чтобы избежать создания бесконечного цикла, который вышел бы из-под контроля и запустил мой счет S3. Я советую вам делать то же самое, когда вы создаете и тестируете любой код, выполнение которого стоит ваших денег.
С этой функцией создание списка объектов в корзине становится легким. Вот все, что нам нужно сделать:
Пример 3. chapter_04/list_bucket_objects_page.php
(отрывок)
<? phperror_reporting (E_ALL); require_once ('cloudfusion.class.php'); require_once ('include / book.inc.php'); $ bucket = IsSet ($ _ GET ['bucket']))? $ _GET ['bucket']: BOOK_BUCKET; $ s3 = new AmazonS3 (); $ objects = getBucketObjects ($ s3, $ bucket); $ fileList = array (); foreach ($ objects как $ object) {$ key = $ object-> Key; $ url = $ s3-> get_object_url ($ bucket, $ key); $ fileList [] = array ('url' => $ url, 'name' => $ key, 'size' => number_format ((int) $ object-> Size)); } $ output_title = "Образец главы 3 - Список объектов S3 в корзине". '$ {bucket}' "; $ output_message =" Простая таблица HTML, отображающая все объекты '.' в корзине '$ {bucket}' . "; включить 'include / list_bucket_objects.html.php'; Выход (0);?>
Этот код генерирует веб-страницу и может принимать необязательный аргумент корзины в строке запроса URL. Давайте разорвем это на части и посмотрим, как это работает:
Этот код проверяет, был ли указан аргумент |
|
Здесь мы вызываем нашу пользовательскую функцию |
|
Следующий шаг — перебрать массив и обработать каждый. |
|
Мы сохраняем три значения для каждого объекта в массиве |
|
Мы включаем наш HTML-шаблон для вывода значений в массиве |
Вот как list_bucket_objects.html.php
HTML-шаблон list_bucket_objects.html.php
:
Пример 4. chapter_04/include/list_bucket_objects.html.php
(выдержка)
<! DOCTYPE html PUBLIC "- // W3C // DTD XHTML 1.0 Strict // EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns =" http : //www.w3.org/1999/xhtml "xml: lang =" en "lang =" en "> <head> <title> <? php echo $ output_title?> </ title> </ head> <body > <h1> <? php echo $ output_title?> </ h1> <p> <? php echo $ output_message?> </ p> <таблица> <thead> <tr> <th> файл </ th> <th > Размер </ th> </ tr> </ thead> <tbody> <? Php foreach ($ fileList as $ file):?> <Tr> <td> <a href = "<? Php echo $ file [' url ']?> "> <? php echo $ file [' name ']?> </a> </ td> <td> <? php echo $ file [' size ']?> </ td> </ tr> <? php endforeach?> </ tbody> </ table> </ body> </ html>
Шаблон $fileList
массив $fileList
и создает строку таблицы для каждого файла, помещая ссылку на файл в первом столбце и размер файла во втором столбце.
Рисунок 1, «Список объектов в корзине S3» показывает, как это выглядит (я уже загрузил некоторые файлы в мою корзину).
Возможно, вы заметили тот факт, что теперь у нас есть все детали, необходимые для создания простого файлового браузера S3. Я оставлю это как вызов для вас. Всего лишь немного поработав, вы сможете соединить list_buckets_page.php
и list_bucket_objects_page.php
.