Streams tutorial.
This commit is contained in:
parent
926d2f18d4
commit
89592860a7
41
doc/streams-tutorial-example.php
Normal file
41
doc/streams-tutorial-example.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../src/HPCloud/Bootstrap.php';
|
||||
|
||||
use \HPCloud\Bootstrap;
|
||||
Bootstrap::useAutoloader();
|
||||
Bootstrap::useStreamWrappers();
|
||||
|
||||
$ini = parse_ini_file(getenv('HOME') . '/.hpcloud.ini');
|
||||
$settings = array(
|
||||
'account' => $ini['account'],
|
||||
'key' => $ini['secret'],
|
||||
'tenantid' => $ini['tenantId'],
|
||||
'endpoint' => $ini['url'],
|
||||
);
|
||||
Bootstrap::setConfiguration($settings);
|
||||
|
||||
// Create a new file and write it to the object store.
|
||||
$newfile = fopen('swift://Example/my_file.txt', 'w');
|
||||
fwrite($newfile, "Good Morning!");
|
||||
fclose($newfile);
|
||||
|
||||
// Check for an object:
|
||||
if (file_exists('swift://Example/my_file.txt')) {
|
||||
print "Found my_file.txt." . PHP_EOL;
|
||||
}
|
||||
|
||||
// Get an entire object at once:
|
||||
$file = file_get_contents('swift://Example/my_file.txt');
|
||||
print 'File: ' . $file . PHP_EOL;
|
||||
|
||||
$cxt = stream_context_create(array(
|
||||
'swift' => array(
|
||||
'account' => $ini['account'],
|
||||
'key' => $ini['secret'],
|
||||
'tenantid' => $ini['tenantId'],
|
||||
'endpoint' => $ini['url'],
|
||||
),
|
||||
));
|
||||
|
||||
print file_get_contents('swift://Example/my_file.txt', FALSE, $cxt);
|
||||
|
238
doc/streams-tutorial.md
Normal file
238
doc/streams-tutorial.md
Normal file
@ -0,0 +1,238 @@
|
||||
Tutorial: Using Stream Wrappers {#streams-tutorial}
|
||||
===============================
|
||||
|
||||
This is an introduction to the HPCloud-PHP library. While the library is
|
||||
large and feature-rich, this tutorial focuses on the Stream Wrapper
|
||||
feature. (There is also a [tutorial about the object-oriented
|
||||
library](@ref 00-tutorial).)
|
||||
|
||||
## TL;DR
|
||||
|
||||
With a few lines of setup code, you can fetch objects from HP Cloud's
|
||||
object storage using built-in PHP functions like this:
|
||||
|
||||
~~~{.php}
|
||||
<?php
|
||||
// Create a new file and write it to the object store.
|
||||
$newfile = fopen('swift://Example/my_file.txt', 'w');
|
||||
fwrite($newfile, "Good Morning!");
|
||||
fclose($newfile);
|
||||
|
||||
// Check for an object:
|
||||
if (file_exists('swift://Example/my_file.txt')) {
|
||||
print "Found my_file.txt." . PHP_EOL;
|
||||
}
|
||||
|
||||
// Get an entire object at once:
|
||||
$file = file_get_contents('swift://Example/my_file.txt');
|
||||
print 'File: ' . $file . PHP_EOL;
|
||||
?>
|
||||
~~~
|
||||
|
||||
In fact, the vast majority of file and stream functions work with
|
||||
HPCloud's `swift://` URLs.
|
||||
|
||||
The rest of this tutorial explains how they work.
|
||||
|
||||
## The Setup
|
||||
|
||||
The example above does not show the code necessary for initializing the
|
||||
HPCloud stream wrapper. In this section, we will look at the necessary
|
||||
setup code.
|
||||
|
||||
### Loading Classes
|
||||
|
||||
The HPCloud PHP library is structured following SPR-0 recommendations.
|
||||
Practically speaking, what this means is that applications that use an
|
||||
SPR-0 autoloader may be able to automatically load the HPCloud library.
|
||||
|
||||
However, we'll assume that that is not the case. We'll assume that the
|
||||
library needs to be initialized manually.
|
||||
|
||||
What we will do is first load the HPCloud Bootstrap.php file, and then
|
||||
use the autoloader in that file to load the rest of the library:
|
||||
|
||||
~~~{.php}
|
||||
<?php
|
||||
require_once '/HPCloud/Bootstrap.php';
|
||||
|
||||
use \HPCloud\Bootstrap;
|
||||
Bootstrap::useAutoloader();
|
||||
Bootstrap::useStreamWrappers();
|
||||
?>
|
||||
~~~
|
||||
|
||||
The first thing the example above does is require the Bootstrap.php
|
||||
file, which contains code necessary for initializing the HPCloud
|
||||
library.
|
||||
|
||||
Next, we call two static methods on the HPCloud::Bootstrap object:
|
||||
|
||||
- Bootstrap::useAutoLoader(): This tells HPCloud to load any other
|
||||
classes on demand. Since we use this, we don't need any more `require`
|
||||
or `include` statements.
|
||||
- Bootstrap::useStreamWrappers(): This tells HPCloud to register its
|
||||
stream wrapper classes.
|
||||
|
||||
In a nutshell, PHP allows libraries to map a particular URL pattern to a
|
||||
stream wrapper. HPCloud registers the `swift://` URL prefix. So any
|
||||
request to a URL beginning with `swift://` will be proxied through the
|
||||
HPCloud library.
|
||||
|
||||
## Setting Up Authentication
|
||||
|
||||
When working with remote HPCloud Object Storage, you must authenticate
|
||||
to the remote system. Authentication requires the following four pieces
|
||||
of information:
|
||||
|
||||
- account: Your account ID
|
||||
- key: Your account's secret key
|
||||
- tenantid: The tenant ID for the services you wish to use
|
||||
- endpoint: The endpoint URL for HPCloud's Identity Services. It usually
|
||||
looks something like this: `https://region-a.geo-1.identity.hpcloudsvc.com:35357`
|
||||
|
||||
All four of these pieces of information can be found in the **API Keys**
|
||||
section of your [management console](https://manage.hpcloud.com)
|
||||
account.
|
||||
|
||||
(Note: You can use your username and password instead of account and
|
||||
key, but you still must supply the tenant ID. Instead of supplying
|
||||
`account` and `key`, use `username` and `password`.)
|
||||
|
||||
We are going to look at two ways to set authentication information. The
|
||||
first is global. That means we supply it once, and all stream and file
|
||||
functions automatically use that information. The second is to pass
|
||||
authentication information into the stream context.
|
||||
|
||||
### Global Configuration
|
||||
|
||||
Supplying global account information has two distinct advantages:
|
||||
|
||||
-# It reduces the complexity of your code
|
||||
-# It allows context-less functions like `file_exists` and `stat` to
|
||||
work.
|
||||
|
||||
But it has a disadvantage: *Only one account can be used at a time.* Since
|
||||
that account's information is shared across all stream wrappers, they
|
||||
all share the same account, tenant Id, and service catalog.
|
||||
|
||||
If you are working on an application that needs to connect to more than
|
||||
one account in the same request, you may find this setup imperfect for
|
||||
your needs.
|
||||
|
||||
That said, here's how we set up a global configuration:
|
||||
|
||||
~~~{.php}
|
||||
$settings = array(
|
||||
'account' => YOUR_ACCOUNT_NUMBER,
|
||||
'key' => YOUR_SECRET_KEY,
|
||||
'tenantid' => YOUR_TENANT_ID,
|
||||
'endpoint' => IDENTITY_SERVICES_URL,
|
||||
|
||||
// Instead of account/key you can use this:
|
||||
// 'username' => YOUR_USERNAME,
|
||||
// 'password' => YOUR_PASSWORD,
|
||||
);
|
||||
Bootstrap::setConfiguration($settings);
|
||||
~~~
|
||||
|
||||
Basically, what we do above is declare an associative array of
|
||||
configuration parameters and then tell HPCloud::Bootstrap to set these
|
||||
as the default configuration.
|
||||
|
||||
Once the above is done, all of those PHP stream and file functions will
|
||||
just work. All you need to do is pass them `swift://` URLs, and they
|
||||
will do the rest.
|
||||
|
||||
## The Format of Swift URLs
|
||||
|
||||
Early in the tutorial we saw some swift URLs like this:
|
||||
`swift://Example/my_file.txt` . What is this URL referencing?
|
||||
|
||||
The URL above has three important parts, in the form
|
||||
`swift://CONTAINER/OBJECT_NAME`.
|
||||
|
||||
- *swift://*: This is the schema. This part of the URL tells PHP to pass
|
||||
the request to the HPCloud stream wrapper. (Siwft, by the way, is the
|
||||
[OpenStack name for object storage](http://openstack.org/projects/storage/).
|
||||
- *Example*: This is the *container name*. In Object Storage parlance, a
|
||||
container is a place to store documents. One account can have lots of
|
||||
containers, and each container can have lots of objects.
|
||||
- *my_file.txt*: This is the object name. An object is basically the
|
||||
same as a file.
|
||||
|
||||
Swift does not support directories, but it does allow slashes in object
|
||||
names. So `swift://Example/this/is/my/file.png' checks the container
|
||||
*Example* for the object named `this/is/my/file.png`.
|
||||
|
||||
(For power users, there are some fancy operations you can do to treat
|
||||
Swift filename parts as if they were directories. Check out
|
||||
HPCloud::Storage::ObjectStorage::Container.)
|
||||
|
||||
## Using Stream Contexts for Authentication
|
||||
|
||||
Sometimes it is better to pass authentication information directly to
|
||||
the stream or file function, instead of relying upon a global
|
||||
configuration. PHP provides for this with **stream contexts**.
|
||||
|
||||
Stream contexts have one major downside: Not all PHP functions accept
|
||||
stream contexts. Here are some notable examples:
|
||||
|
||||
- file_exists()
|
||||
- is_readable()
|
||||
- stat()
|
||||
|
||||
(Basically, anything that calls the underlying `stat(3)`.)
|
||||
|
||||
The advantage, though, is that each call can have its own authentication
|
||||
data. This is good for supporting multiple accounts, and can also be
|
||||
used to optimize long-term performance (e.g. by saving authentication
|
||||
tokens in a database and re-using them).
|
||||
|
||||
Here's how a stream context is used:
|
||||
|
||||
~~~{.php}
|
||||
<?php
|
||||
require_once __DIR__ . '/../src/HPCloud/Bootstrap.php';
|
||||
|
||||
use \HPCloud\Bootstrap;
|
||||
Bootstrap::useAutoloader();
|
||||
Bootstrap::useStreamWrappers();
|
||||
|
||||
$cxt = stream_context_create(array(
|
||||
'swift' => array(
|
||||
'account' => YOUR_ACCOUNT_NUMBER,
|
||||
'key' => YOUR_SECRET_KEY,
|
||||
'tenantid' => YOUR_TENANT_ID,
|
||||
'endpoint' => IDENTITY_SERVICES_URL,
|
||||
|
||||
// Instead of account/key you can use this:
|
||||
// 'username' => YOUR_USERNAME,
|
||||
// 'password' => YOUR_PASSWORD,
|
||||
),
|
||||
));
|
||||
|
||||
print file_get_contents('swift://Example/my_file.txt', FALSE, $cxt);
|
||||
?>
|
||||
~~~
|
||||
|
||||
The main difference is the creation of `$cxt` using PHP's
|
||||
`stream_context_create()`. To fully understand this, you may want to
|
||||
take a look at the [PHP documentation](http://us3.php.net/manual/en/book.stream.php)
|
||||
for streams.
|
||||
|
||||
## Summary
|
||||
|
||||
This tutorial is focused on using stream wrappers to interact with your
|
||||
HPCloud Object Storage service. We focused on configuring the
|
||||
environment for transparently using PHP functions like `fopen()` and
|
||||
`file_get_contents()` to work with objects in HPCloud's object storage.
|
||||
|
||||
This is just one way of interoperating with the HPCloud library. For
|
||||
more detail-oriented work, you may find the Object Oriented facilities
|
||||
better suited. You can read [the OO tutorial](@ref oo-tutorial) to learn
|
||||
more about that.
|
||||
|
||||
Addidtionally, you may wish to learn more about the internals of the
|
||||
stream wrapper, the main class,
|
||||
HPCloud::Storage::ObjectStorage::StreamWrapper, is well-documented.
|
Loading…
x
Reference in New Issue
Block a user