Git Product home page Git Product logo

softlayer-object-storage-php's Introduction

SoftLayer Object Storage PHP Client

PHP bindings for SoftLayer Object Storage

Install

Unzip the files and make sure to include lib/ObjectStorage/Util.php once somewhere in your script

Requirements

* Mandatory
    * PHP version > 5.2
	* PHP OpenSSL extension (if your PHP is compiled by your self, make sure compile it with: --with-openssl configure)
* Optional
    * Zend Framework (for HTTP Client)
    * CURL

Documents

Documents are generated by PHPDocumentor. See docs directory for details.

Tests

The test cases are run using phpunit version PHPUnit 3.5.13 To run a test, provide your object storage credentials in test/BaseTest.php file.

Examples

Configuring Object Storage

// If you want to cache ObjectStorage authentication token:
$tokenStore = ObjectStorage_TokenStore::factory('file', array('ttl' => 3600, 'path' => '/tmp/objectStorage'));
ObjectStorage::setTokenStore($tokenStore);

// If no adapter option is provided, CURL will be used.
$options = array('adapter' => ObjectStorage_Http_Client::SOCKET, 'timeout' => 10);
 $host = 'https://dal05.objectstorage.softlayer.net'; // the SoftLayer Object Storage API host
 $username = 'SLOS778231112-1:3241234'; // user name and password is display at https://manage.softlayer.com/ObjectStorage/index
 $password = 'ksd83ksd8ksdfhx823ks8cksew8slsdi82ls8xlsd8l';

$objectStorage = new ObjectStorage($host, $username, $password, $options);

Basic CRUD

$containerList = $objectStorage->with()->get();

$containerName = $containerList->getPath();

$shallowContainer = $objectStorage->with('example_container');

$newContainer = $shallowContainer->create();

$updatedContainer = $newContainer->setMeta('Description', 'Adding a meta data')->update();

$reloadedContainer = $newContainer->get();

$result = $newContainer->delete();

// Creating an object is similar to that of container CRUD
// This library will try to guess the content-type for an object if you don't provide it.
// An object without an extension (pseudo sub-directory) will have application/directory content-type.
$newObject = $objectStorage->with('example_container/object.txt')
                            ->setBody('test object')
                            ->setMeta('description', 'first test file')
                            ->create();

// You can copy a local file to Object Storage.
// This will stream local file data to Object Storage. Keep in mind, most PHP configurations will support a file size up to 2 GB.
$newObject = $objectStorage->with('example_container/large_file.zip')
                            ->setLocalFile('/path/to/local/file')
                            ->setMeta('description', 'large local file upload')
                            ->setHeader('Content-type', 'application/zip')
                            ->create();

// You can copy a remote file in Object Storage.
// This will trigger a remote copy on the cluster (which is significantly faster than streaming down and up the file/headers).
$newObject = $objectStorage->with('example_container/large_file_duplicate.zip')
                            ->copyFrom('/example_container/large_file.zip')
                            ->create();

// If you wanted, you can do this all one line.
// Most functions return itself so you can chain method calls except delete method which returns a boolean value.
$result = $objectStorage->with('example_container')
                        ->create()
                        ->setMeta('Description', 'Adding a meta data')
                        ->update()
                        ->get()
                        ->delete();

// When you create a new container or an object, ObjectStorage_Abstract will return itself, not the newly created container or object.
// If you wish to reload the data from ObjectStorage cluster, use ObjectStorage_Abstract::get or ObjectStorage_Abstract::reload methods.
// It will fetch the container info from ObjectStorage and reload $newContainer object with it.
$newContainer = $objectStorage->with('example_container')->create()->reload();

CDN operations

// To create a CDN enabled container
$objectStorage->with('cdn_container')->enableCdn()->create();

// To update an existing container to a CDN enabled container
$objectStorage->with('another_container')->enableCdn()->setTtl(3600)->update();

// You want to see CDN URLs?
$cdnUrls = $container->getCdnUrls();

// CDN purge cache. (In case you modified an object and need to refresh CDN cache.)
$objectStorage05->with('cdn_container/object')->purgeCache();

// CDN load cache
$objectStorage05->with('cdn_container/object')->loadCache();

// If you want to compress *text* files served via CDN.
$results = $objectStorage05->with('')->setContext('cdn')
                    ->setHeader('X-CDN-COMPRESSION', 'true') // Set to "false" to turn off compression
                    ->setHeader('X-CDN-COMPRESSION-MIME', 'text/plain,text/html,text/css,application/x-javascript,text/javascript')
                    ->update();

// If you want to add a custom CDN CNAME. (
// You can add a CNAME to a container level as well. To do so, pass an appropriate container name to with() method
// Keep in mind you can have only one custom CNAME per container
// To find your CNAME endpoint, use "dig" command on your existing CDN host. For example,
// $ dig 1234.http.dal05.cdn.softlayer.net
$results = $objectStorage05->with('')->setContext('cdn')
                    ->setHeader('X-CDN-CNAME-Action', 'add') // Use "delete" if you wish to delete a CNAME
                    ->setHeader('X-Cdn-CNAME', 'cdn.mysite.com')
                    ->update();

Traversing containers or objects

$container = $objectStorage->with('another_container')->get();
if (count($container->objects) > 0) {
    foreach ($container->objects as $shallowObject) {
        $object = $shallowObject->get(); // Defaults to 100 results, pass a parameter to override eg. ->get(500)

        echo $object->getUrl();
        echo $object->getBody();
    }
}

Pseudo-hierarchical directories

/**
 * If you have a container and an object as below and you want to retrieve pseudo sub-directories,
 * use the "prefix" and "delimiter" query parameters.
 *
 * - some_container/sub_dir/2012/object.file
 */

$container = $objectStorage01->with('some_container')
                ->setParam('delimiter', '/')
                ->setParam('prefix', '')
                ->setMime('json')
                ->get();

// Response body (json) will include {"subdir":"sub_dir/"}
// You can traverse to the final object by setting the "subdir" value as the new "prefix" value.
// To retrieve the next level pseudo directory:
...
            ->setParam('prefix', 'sub_dir/');
...

Pagination

/**
 * You can traverse the directories through pages of data using markers.
 *
 */

$container = $objectStorage01->with('some_container')
                ->setParam('marker', '/some_container/last_item_name_on_previous_page.jpg')
                ->get(25);

// You can progress backwards through the directories using "end_marker" too

$container = $objectStorage01->with('some_container')
                ->setParam('end_marker', '/some_container/first_item_name_on_previous_page.jpg')
                ->get(25);

Copy an object to another Object Storage

$objectStorage01 = new ObjectStorage($host01, $username01, $password01);
$objectStorage02 = new ObjectStorage($host02, $username02, $password02);

$object = $objectStorage01->with('container/object')->get();
$objectStorage02->create($object);

Search

$objectOrContainer = $objectStorage05->with('')
                                    ->setContext('search')
                                    ->setFilter('type', 'container')
                                    ->setFilter('q', $searchKeyword)
                                    ->setMime('json')
                                    ->get();

Notes

ObjectStorage_Abstract has many properties but these three are the major componets.

* $objectStorage: holds reference to a ObjectStorage object (optional)
* $request: HTTP request object is consisted of headers and body
* $response: HTTP response object is consisted of headers and body

You can access to HTTP request or response object using ObjectStorage_Abstract::getRequest or ObjectStorage_Abstract::getResponse. You can also use convenience getter and setters. These can help you avoid doing like this:

$container->getResponse()->setMeta('description', 'example meta');
$container->getRequest()->getBody();

But you can do this instead:

$container->setMeta('description', 'example meta');
$container->getBody();

The idea is that you set data to HTTP request and get data from HTTP response.

softlayer-object-storage-php's People

Contributors

adamh114 avatar briancline avatar crackerjackmack avatar dvsoftware avatar etaoins avatar follower46 avatar its-clee avatar lorenzoaiello avatar martinj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

softlayer-object-storage-php's Issues

Proper user-agent

Set a proper user-agent header in each of the HTTP adapters to identify this particular library; the version should be included (see also #23).

delete() throwing exception on 404 instead of returning false

I'm making the following call:
$res = $os->with('container/filename.txt')->delete();

But instead of $res getting set to a boolean value, an exception is being thrown, which is not being caught, so a fatal error occurs:

Error level: 1
Error message: Uncaught exception 'ObjectStorage_Exception_Http_NotFound' with message 'Not Found' in /var/www/vhosts/jjriv.assignthis.com/app/LocalLib/ObjectStorage/ObjectStorage.php:531
Stack trace:
#0 /var/www/vhosts/jjriv.assignthis.com/app/LocalLib/ObjectStorage/ObjectStorage/Exception/Http.php(10): ObjectStorage_Exception_Http->throwException(404, NULL, '/var/www/vhosts...', 531)
#1 /var/www/vhosts/jjriv.assignthis.com/app/LocalLib/ObjectStorage/ObjectStorage.php(531): ObjectStorage_Exception_Http->__construct(NULL, 404)
#2 /var/www/vhosts/jjriv.assignthis.com/app/LocalLib/ObjectStorage/ObjectStorage/Abstract.php(607): ObjectStorage->delete(Object(ObjectStorage_Object))
#3 /var/www/vhosts/jjriv.assignthis.com/app/cron/upload_garbage_collection.php(56): ObjectStorage_Abstract->delete()

But in the unit test docs, the delete() is not performed inside a try/catch clause:
https://github.com/softlayer/softlayer-object-storage-php/blob/master/tests/ObjectTest.php

And according to the Openstack documentation, 404 is a valid response for when the object does not exist:
http://docs.openstack.org/api/openstack-object-storage/1.0/content/delete-object.html

Do I need to put my delete() code inside a try/catch or is this a bug? Thanks!

Initialization error exception

The file lib\ObjectStorage\Abstract.php has error in line 352 throw new ObjectStorage_Exception(null, 'Invalid MIME type is provided.');.
It must be throw new ObjectStorage_Exception('Invalid MIME type is provided.');

Traversing prefixed container to get all objects, but getObjectCount() returns number of all objects in the container without prefix

The following code is expected to return all objects under the given prefix as $container->objects

$client = new ObjectStorage($host, $username, $password);
$objectToRequest = 10000;
$container = $client->with('container')->setParam('prefix','a prefix')->get($objectToRequest);
while (count($container->objects) < $container->getObjectCount()) {
    $obj = end($container->objects);
    reset($container->objects);
    $marker = $obj->getPath();
    $container->get($objectToRequest, $marker);
}

However, the code runs indefinitely. And when I add:

echo count($container->objects).' = '.$container->getObjectCount();

in the loop, I see that the values are static where $container->getObjectCount() shows the number of all objects in the unprefixed container, while count($container->objects) shows the number of all objects in the prefixed container.

The reason for the loop is because get() maximum returns 10000 objects per call, so for prefixes which have more than 10000 objects the call must be repeated with marker as last retrieved object.

My question is:

  1. Is my understanding about the methods correct?
  2. Is the above code correct? i.e. doing what I intend to do as explained above? If not, what's the correct one?

Regards,

Mario

Integration with Bluemix

Is this compatible with bluemix?
I tried to do credentials and pull my container

this always come
Fatal error: Uncaught ObjectStorage_Exception_Http_NotFound: Not Found in /Applications/XAMPP/xamppfiles/htdocs/jti-ats/vendor/softlayer/objectstorage/lib/ObjectStorage.php:166 Stack trace: #0 /Applications/XAMPP/xamppfiles/htdocs/jti-ats/vendor/softlayer/objectstorage/lib/ObjectStorage.php(166): ObjectStorage_Exception_Http::factory('Not Found', 404) #1 /Applications/XAMPP/xamppfiles/htdocs/jti-ats/vendor/softlayer/objectstorage/lib/ObjectStorage.php(94): ObjectStorage->authenticate() #2 /Applications/XAMPP/xamppfiles/htdocs/jti-ats/vendor/softlayer/objectstorage/lib/ObjectStorage.php(604): ObjectStorage->getAuthenticationData() #3 /Applications/XAMPP/xamppfiles/htdocs/jti-ats/vendor/softlayer/objectstorage/lib/ObjectStorage/Abstract.php(608): ObjectStorage->delete(Object(ObjectStorage_Container)) #4 /Applications/XAMPP/xamppfiles/htdocs/jti-ats/test.php(18): ObjectStorage_Abstract->delete() #5 {main} thrown in /Applications/XAMPP/xamppfiles/htdocs/jti-ats/vendor/softlayer/objectstorage/lib/ObjectStorage.php on line 166

Issue on search container

When using this function, it responded only old container. New containers did NOT respond.

$objects = $this->_object_storage
->with('')
->setContext('search')
->setFilter('type', 'container') // object or container
->setFilter('', '')
->setMime('json') //json - xml - plain
->get();

How can i fix it?

Thanks

Versioning

This project needs some versioning love so we can better manage releases and properly version any API-breaking changes.

Readme.markdown

Under the section titled "Traversing containers or objects"

foreach ($results->objects as $shallowObject) {

should be changed to

foreach ($container->objects as $shallowObject) {

Get Modified date

How can i get modified date of file on Object Storage?
Could you please give me a sample code?

Thank you very much

Client.php

I am currently implementing the PHP code for the Object Storage system.

Everything seems to be working fine, however, I'm receiving an error about an "Undefined variable".

Notice: Undefined variable: host in /lib/ObjectStorage/Http/Client.php on line 45

Notice: Undefined variable: host in /lib/ObjectStorage/Http/Client.php on line 54

Notice: Undefined variable: host in /lib/ObjectStorage/Http/Client.php on line 62

Notice: Undefined variable: host in /lib/ObjectStorage/Http/Client.php on line 66

The variable in question is:
self::$client[$host]

The $host key is not defined anywhere in this class. I was able to correct the problem by changing $host from a variable into a string "host".

Is this correct??

Progress of Uploading?

HI

How can i get progress when uploading very big file? Is there hook for this?

thanks

Support for arbitrary CURL options, or at least for connect timeout option

Please provide a way to set arbitrary CURL options, or at least all timeout settings.

When trying to load large objects, the request may time out.
To work around this, you can set the timeout for the entire request to a few minutes maybe.

However this may cause your downloads to wait for a very long time if there are connection issues, because CURL defaults to very high timeout values e.g. for the connect phase (5 minutes), which you may not want.

Looking at the source of ObjectStorage_Http_Adapter_Curl, it seems that there are only a few hard-coded CURL options that can be set at all.

Rather than hard-code yet another option, I think it would be better to just provide a generic way to set any CURL option, e.g. via an array curloptions in the $options argument to the ObjectStorage constructor.

Socket.php SSL3_WRITE_PENDING:bad write retry on Create()

Hi,

Thought I would log this issue.

Here is the 'out-of-the-box' code I am using for uploading files:

$options = array('adapter' => ObjectStorage_Http_Client::SOCKET, 'timeout' => 10);
$objStorage = new ObjectStorage('', '', '', $options);

try {
   $newFile = $objStorage->with('RemoteFilePath')
                   ->setLocalFile($PathTolocalFile)
                   ->create();

   return $newFile->getUrl();
}
catch (Exception $e) {
   return $e->getMessage();
}

For some reason, uploading a file that is under 1Mb works. But any file with a size bigger than this, the ->create() request eventually times out, no exception is thrown and I keep getting these error in my log:

xxx.xxx.xxx.xx - [05/06/16 03:47:02] Warning: fwrite(): SSL operation failed with code 1. OpenSSL Error messages:
error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry (/var/www/vendor/softlayer/objectstorage/lib/ObjectStorage/Http/Adapter/Socket.php:132)

As those bindings are essentially a wrapper round curl, I then tested with CURL myself see if I could upload a file bigger than 1M to Softlayer Storage Container. It turns out it succeeded using CURL both on my dev machine and staging server!

curl -i -XPUT -H "X-Auth-Token: {{MyAuthToken}}" --data-binary "@BigFile.txt" https://lon02.objectstorage.softlayer.net/v1/{{MyAuthTokenKey}}/{{MyContainer}}/BigFile.txt

Have you ever come across this? Is this my machine?
Thanks

Support for TLSv1?

We currently use this library and it works great. But, today SoftLayer turned off SSLv3 on their ObjectStorage network in response to the POODLE vulnerability.

Is there any way to use this library with the CURL adapter and TLSv1?

At present, it doesn't work at all :(

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.