Статьи

Использование Rackspace PHP SDK

Как следует из моей предыдущей статьи , CloudFiles — это онлайн-сервис хранения статического контента.

Rackspace предоставляет комплект разработчика программного обеспечения (SDK) для нескольких языков программирования. Они хранят свой PHP SDK на GitHub . Для PHP SDK требуется PHP 5 со следующими модулями: cURL, FileInfo и mbstring.

В этом уроке мы рассмотрим использование PHP SDK с CloudFiles. Не все части API будут рассмотрены, но вы получите хорошее начало.

После загрузки SDK вам понадобятся только следующие файлы и папки:

  • доля/
  • cloudfiles.php
  • cloudfiles_exceptions.php
  • cloudfiles_http.php

Ваш первый рейс

Начиная у нас есть несколько основных задач. Нам нужно загрузить файл cloudfiles.php, пройти аутентификацию с помощью CloudFiles и создать соединение с помощью нашего токена аутентификации.

<?php $your_username = 'jeffk'; $your_api_key = 'longrandomapikey'; require 'cloudfiles.php'; /** * Authenticate using your Rackspace Cloud username and your API key obtained from the control panel **/ $auth = new CF_Authentication($your_username, $your_api_key); /** * If you use Cloud Files in the UK use **/ $auth = new CF_Authentication($your_username, $your_api_key, null, UK_AUTHURL); $auth->authenticate(); /** * Now we create the connection with our CF_Authentication instance **/ $connection = new CF_Connection($auth); ?> 

Это так просто. Теперь, когда мы подключены, наш следующий шаг — взаимодействие с контейнером.

Контейнеры

Мы можем создавать, удалять, перечислять и открывать различные контейнеры. Для взаимодействия с любым контейнером мы будем использовать наш объект $ connection, который мы создали выше.

Давайте рассмотрим создание контейнера, в котором будут храниться наши файлы.

 <?php /** * To create a container, use the $connection variable and call the create_container method. If the container * already exists it will return a container instance and NOT overwrite the container. **/ $images = $connection->create_container("images"); ?> 

Это вернет объект контейнера. В примере мы назвали его $images . Это будет использоваться для управления контейнером вместе с любыми объектами в нем. Если вам нужно взаимодействовать с какими-либо объектами в контейнере, вы должны использовать метод create_container чтобы получить к нему доступ. Поскольку контейнер уже существует, он вернет экземпляр и не перезапишет его.

Теперь удаляем контейнер, который больше не нужен. Примечание: вы не можете удалить контейнер, в котором есть объекты (файлы). Если в нем есть файлы, вы должны удалить их все до удаления контейнера. В конце статьи есть фрагмент для удаления всех объектов, а затем удаления контейнера.

 <?php /** * To delete a container call the delete_container method. **/ $connection->delete_container("images"); ?> 

С этими действиями, как насчет получения контейнеров? Если вам нужен массив ваших контейнеров с различной информацией, вы можете использовать метод get_containers .

 <?php /** * Get an array of your available containers and display them. **/ $containers = $connection->get_containers(); foreach($containers as $container) { echo 'Name: '. $container->name; echo 'Number of Objects: '. $container->count; echo 'Bytes Stores: '.$container->bytes; } ?> 

Если вам нужны только имена контейнеров, у нас есть метод list_containers:

 <?php $containers = $connection->list_containers(); print_r($containers); // Returns Array([0] => "images") ?> 

Сделать его доступным для CDN

По умолчанию все контейнеры являются частными. Чтобы сделать их доступными в сети доставки контента и доступными по URL, мы должны сообщить API, чтобы сделать контейнер общедоступным. Естественно, мы можем вернуть его в частную, если это будет необходимо.

 <?php /** * To make a container public use the containers instance and call make_public. You can * optionally include a timestamp for how long the file is cached on the CDN network. The * default is 86400 (1 day) * Calling this method returns the URI the container is available at. **/ $public_uri = $images->make_public(); /** * You can also get the URI by calling the cdn_uri or cdn_ssl_uri attributes **/ $uri => $images->cdn_uri; $https_uri = $images->cdn_ssl_uri; /** * To set a public container private you can call make_private. However, all the files in this container will still be available until the cache time expires. **/ $images->make_private(); ?> 

Объекты, предметы, объекты

Чтобы создать объект, мы должны перенести наш экземпляр контейнера и использовать метод create_object с именем файла. Как только мы это сделаем, мы должны отправить содержимое файла. Есть два способа сделать это. Самый простой способ — использовать метод load_from_filename чтобы он собирал всю информацию для нас. Вторым способом мы указываем файл и размер.

 <?php $avatar = $images->create_object('jeffs_avatar.jpg'); $avatar->load_from_filename('/home/user/photos/jeffs_avatar.jpg'); $file_name = '/home/user/photos/jeffs_avatar.jpg'); $file_size = (float) sprintf("%u", filesize($file_name)); $fp = open($file_name, 'r'); $avatar->write($fp, $file_size); ?> 

Чтобы получить частный объект, мы можем использовать метод steam. Это работает очень хорошо для защиты контента. Это не только изображения, если вы хотите ограничить доступ к документу в формате pdf только для своих членов, это было бы идеально.

 <?php $img = $images->get_object('jeff.jpg'); header('Content-Type: '.$img->content_type); $output = fopen("php://output", "w"); $img->stream($output); fclose($output); ?> 

Чтобы удалить объект, нам нужно использовать наш контейнер и вызвать метод delete_object.

 <?php $images->delete_object('jeff.jpg'); ?> 

Заканчивать. Несколько рабочих примеров

Здесь у нас есть пример сканирования папки для файлов .jpg и загрузки их в Rackspace Cloud Files.

 <?php $api_username = 'jeffk'; $api_key = 'myapikey'; $file_path = '/home/user/images'; require 'cloudfiles.php'; $auth = new CF_Authentication($api_username, $api_key); $auth->authenticate(); $connection = new CF_Connection($auth); $images = $connection->create_container("images"); $url = $images->make_public(); echo 'The url is '.$url; /** * Now that we have our connection and access to the container lets get our files. **/ if ($h = opendir($file_path)) { /** * We just opened the directory and now we are going to scan that directory for any files **/ while (false !== ($file = readdir($h))) { /** * Now we are going to get the extension of the file. If it matches "jpg" then we are going to upload it. * Otherwise we are going to ignore it. **/ $get_extension = explode('.', $file); if ($get_extension[count($get_extension)-1]=='jpg') { /** * Lets create the object and send it to CloudFiles **/ $img = $images->create_object($file); $img->load_from_filename($file_path.'/'.$file); /** Now we delete the image so we don't try to upload it again if we rerun the script **/ unset($img); } } /** * Close the handler for good measure **/ closedir($h); } ?> с <?php $api_username = 'jeffk'; $api_key = 'myapikey'; $file_path = '/home/user/images'; require 'cloudfiles.php'; $auth = new CF_Authentication($api_username, $api_key); $auth->authenticate(); $connection = new CF_Connection($auth); $images = $connection->create_container("images"); $url = $images->make_public(); echo 'The url is '.$url; /** * Now that we have our connection and access to the container lets get our files. **/ if ($h = opendir($file_path)) { /** * We just opened the directory and now we are going to scan that directory for any files **/ while (false !== ($file = readdir($h))) { /** * Now we are going to get the extension of the file. If it matches "jpg" then we are going to upload it. * Otherwise we are going to ignore it. **/ $get_extension = explode('.', $file); if ($get_extension[count($get_extension)-1]=='jpg') { /** * Lets create the object and send it to CloudFiles **/ $img = $images->create_object($file); $img->load_from_filename($file_path.'/'.$file); /** Now we delete the image so we don't try to upload it again if we rerun the script **/ unset($img); } } /** * Close the handler for good measure **/ closedir($h); } ?> 

Следующий пример — удаление контейнера, который уже содержит объекты.

 <?php $objects = $images->list_objects(); if (count($objects)>0) { foreach($objects as $o) { $images->delete_object($o); } } $connection->delete_container("images"); ?> 

То, что я привел здесь, было несколько основных примеров. Несколько вещей, которые вы можете добавить, — это возвращать URL-адрес объектам, обрабатывать ошибки или даже убедиться, что перед подключением есть 1 или более объектов, ожидающих загрузки

Дополнительная необходимость знать

Если вы видите ошибку, как показано ниже, вам необходимо обновить ваши сертификаты CA, обратитесь к руководству по вашей ОС или веб-хосту, чтобы обновить их. После успешного тестирования в моей среде разработки я столкнулся с этой проблемой на производстве.

 * About to connect() to lon.auth.api.rackspacecloud.com port 443 * Trying 212.64.148.13... * connected * Connected to lon.auth.api.rackspacecloud.com (212.64.148.13) port 443 * successfully set certificate verify locations: * CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none * SSL certificate problem, verify that the CA cert is OK. Details: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed * Closing connection #0 PHP Fatal error: Uncaught exception 'InvalidResponseException' with message 'Unexpected response (): ' in /usr/share/php/cloudfiles/cloudfiles.php:212 Stack trace: #0 /var/www/html/cloudtest.php(18): CF_Authentication->authenticate() #1 {main} thrown in /usr/share/php/cloudfiles/cloudfiles.php on line 212 Fatal error: Uncaught exception 'InvalidResponseException' with message 'Unexpected response (): ' in /usr/share/php/cloudfiles/cloudfiles.php:21 

Далее Rackspace использует исключения при возникновении ошибок. Оборачивая ваш код в блоки try {} catch () {}, вы получите сообщение об ошибке вместо «Uncaught исключения…». В списке ниже вы можете увидеть различные используемые ими классы исключений и то, что они расширяют только предоставленный класс Exception. по тел.

 class SyntaxException extends Exception { } class AuthenticationException extends Exception { } class InvalidResponseException extends Exception { } class NonEmptyContainerException extends Exception { } class NoSuchObjectException extends Exception { } class NoSuchContainerException extends Exception { } class NoSuchAccountException extends Exception { } class MisMatchedChecksumException extends Exception { } class IOException extends Exception { } class CDNNotEnabledException extends Exception { } class BadContentTypeException extends Exception { } class InvalidUTF8Exception extends Exception { } class ConnectionNotOpenException extends Exception { } 

Если бы вы попытались удалить контейнер, в котором все еще были объекты, комплект разработки программного обеспечения сгенерировал бы исключение NonEmptyContainerException, которое вы должны отслеживать.

 <?php /** * Try to run the code **/ try { $connection->delete_container("images"); } /** * If there was an exception thrown, catch it and display the message **/ catch(NonEmptyContainerException $e) { echo $e->getMessage(); } 

Если бы наш контейнер не был пустым, на нем было бы сообщение «Контейнер должен быть пустым до его удаления». Если вы не уловили ошибку, она выдаст такой результат:

 Fatal error: Uncaught exception 'NonEmptyContainerException' with message 'Container must be empty prior to removing it.' in /Users/kreitje/Development/test/ cloudfiles.php:560 Stack trace: #0 /Users/kreitje/Development/test/index.php(25): CF_Connection->delete_container('images') #1 {main} thrown in /Users/kreitje/ Development/test/cloudfiles.php on line 560 

Если вы разрабатываете приложение, с которым клиенты будут взаимодействовать, вы захотите поймать любое исключение Иногда отображаемая ошибка отображает конфиденциальную информацию. Выше вы можете увидеть, где хранятся мои файлы. В зависимости от ошибки, возможно, ваши учетные данные API могут отображаться на странице браузера.

В комплекте для разработки программного обеспечения есть папка с документами, в которой рассматриваются эти методы, а также несколько дополнительных. Теперь, когда вы ознакомились с основами и знаете, где находится документация, я призываю вас создать проект, взаимодействующий с Rackspace CloudFiles.

Артюш изображения на Shutterstock