Skip to content

How to use the PHP client

jsteemann edited this page Feb 28, 2013 · 2 revisions

<a name="setting_up_connection_options"/a>

Setting up the connection options

In order to use ArangoDB, you need to specify the connection options. We do so by creating a PHP array $connectionOptions. Put this code into a file named test.php in your current directory:

// use the following line when using packagist/composer
// require dirname(__FILE__) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . '.composer' . DIRECTORY_SEPARATOR . 'autoload.php';

// use the following line when using git
require dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ArangoDB-PHP' . DIRECTORY_SEPARATOR . 'autoload.php';

// set up some aliases for less typing later
use triagens\ArangoDb\Connection as ArangoConnection;
use triagens\ArangoDb\ConnectionOptions as ArangoConnectionOptions;
use triagens\ArangoDb\DocumentHandler as ArangoDocumentHandler;
use triagens\ArangoDb\Document as ArangoDocument;
use triagens\ArangoDb\Exception as ArangoException;
use triagens\ArangoDb\ConnectException as ArangoConnectException;
use triagens\ArangoDb\ClientException as ArangoClientException;
use triagens\ArangoDb\ServerException as ArangoServerException;
use triagens\ArangoDb\UpdatePolicy as ArangoUpdatePolicy;
use triagens\ArangoDb\Statement as ArangoStatement;
use triagens\ArangoDb\Cursor as ArangoCursor;

// set up some basic connection options
$connectionOptions = array(
    // server endpoint to connect to
    ArangoConnectionOptions::OPTION_ENDPOINT => 'tcp://127.0.0.1:8529',
    // authorization type to use (currently supported: 'Basic')
    ArangoConnectionOptions::OPTION_AUTH_TYPE => 'Basic',
    // user for basic authorization
    ArangoConnectionOptions::OPTION_AUTH_USER => 'root',     
    // password for basic authorization
    ArangoConnectionOptions::OPTION_AUTH_PASSWD => '', 
    // connection persistence on server. can use either 'Close' (one-time connections) or 'Keep-Alive' (re-used connections)
    ArangoConnectionOptions::OPTION_CONNECTION => 'Close',  
    // connect timeout in seconds
    ArangoConnectionOptions::OPTION_TIMEOUT => 3,
    // whether or not to reconnect when a keep-alive connection has timed out on server
    ArangoConnectionOptions::OPTION_RECONNECT => true,
    // optionally create new collections when inserting documents
    ArangoConnectionOptions::OPTION_CREATE => true,
    // optionally create new collections when inserting documents
    ArangoConnectionOptions::OPTION_UPDATE_POLICY => ArangoUpdatePolicy::LAST,
);

$connection = new ArangoConnection($connectionOptions);

This will make the client connect to ArangoDB

  • running on localhost (OPTION_HOST)
  • on the default port 8529 (OPTION_PORT)
  • with a connection timeout of 3 seconds (OPTION_TIMEOUT)

When creating new documents in a collection that does not yet exist, you have the following choices:

  • auto-generate a new collection: if you prefer that, set OPTION_CREATE to true
  • fail with an error: if you prefer this behavior, set OPTION_CREATE to false

When updating a document that was previously/concurrently updated by another user, you can select between the following behaviors:

  • last update wins: if you prefer this, set OPTION_UPDATE_POLICY to last
  • fail with a conflict error: if you prefer that, set OPTION_UPDATE_POLICY to conflict

<a name="creating_collection"/a>

Creating a collection

This is just to show how a collection is created.
For these examples it is not needed to create a collection prior to inserting a document, as we set ArangoConnectionOptions::OPTION_CREATE to true.

So, after we get the settings, we can start with creating a collection. We will create a collection named "users".

The below code will first set up the collection locally in a variable name $user, and then push it to the server and return the collection id created by the server:

$collectionHandler = new CollectionHandler($connection);

// create a new document
$userCollection = new ArangoCollection();
$userCollection->setName('user');
$id = $collectionHandler->add($userCollection);

// print the collection id created by the server
var_dump($id);

<a name="creating_document"/a>

Creating a document

After we created the collection, we can start with creating an initial document. We will create a user document in a collection named "users". This collection does not need to exist yet. The first document we'll insert in this collection will create the collection on the fly. This is because we have set OPTION_CREATE to true in $connectionOptions.

The below code will first set up the document locally in a variable name $user, and then push it to the server and return the document id created by the server:

$handler = new ArangoDocumentHandler($connection);

// create a new document
$user = new ArangoDocument();

// use set method to set document properties
$user->set("name", "John");
$user->set("age", 25);

// use magic methods to set document properties
$user->likes = array('fishing', 'hiking', 'swimming');

// send the document to the server
$id = $handler->add('users', $user);

// print the document id created by the server
var_dump($id);

Document properties can be set by using the set() method, or by directly manipulating the document properties.

As you can see, sending a document to the server is achieved by calling the add() method on the client library's DocumentHandler class. It needs the collection name ("users" in this case") plus the document object to be added. add() will return the document id as created by the server. The id is a numeric value that might or might not fit in a PHP integer.

<a name="adding_exception_handling"/a>

Adding exception handling

The above code will work but it does not check for any errors. To make it work in the face of errors, we'll wrap it into some basic exception handlers

try {
$connection = new ArangoConnection($connectionOptions);
$handler = new ArangoDocumentHandler($connection);

// create a new document
$user = new ArangoDocument();

// use set method to set document properties
$user->set("name", "John");
$user->set("age", 25);

// use magic methods to set document properties
$user->likes = array('fishing', 'hiking', 'swimming');

// send the document to the server
$id = $handler->add('users', $user);

// print the document id created by the server
var_dump($id);
} catch (ArangoConnectException $e) {
  print 'Connection error: ' . $e->getMessage() . PHP_EOL;
} catch (ArangoClientException $e) {
  print 'Client error: ' . $e->getMessage() . PHP_EOL;
} catch (ArangoServerException $e) {
  print 'Server error: ' . $e->getServerCode() . ':' . $e->getServerMessage() . ' ' . $e->getMessage() . PHP_EOL;
}

<a name="retrieving_document"/a>

Retrieving a document

To retrieve a document from the server, the get() method of the DocumentHandler class can be used. It needs the collection name plus a document id. There is also the getById() method which is an alias for get().

// get the document back from the server
$userFromServer = $handler->get('users', $id);
var_dump($userFromServer);


The result of the get() method is a Document object that you can use in an OO fashion:

object(triagens\ArangoDb\Document)##6 (4) {
    ["_id":"triagens\ArangoDb\Document":private]=>
    string(15) "2377907/4818344"
    ["_rev":"triagens\ArangoDb\Document":private]=>
    int(4818344)
    ["_values":"triagens\ArangoDb\Document":private]=>
    array(3) {
        ["age"]=>
        int(25)
        ["name"]=>
        string(4) "John"
        ["likes"]=>
        array(3) {
            [0]=>
            string(7) "fishing"
            [1]=>
            string(6) "hiking"
            [2]=>
            string(8) "swimming"
        }
    }
    ["_changed":"triagens\ArangoDb\Document":private]=>
    bool(false)
}

Whenever the document id is yet unknown, but you want to fetch a document from the server by any of its other properties, you can use the getByExample() method. It allows you to provide an example of the document that you are looking for. The example should either be a Document object with the relevant properties set, or, a PHP array with the propeties that you are looking for:

$cursor = $handler->getByExample('users', array('name'=>'John'));
var_dump($cursor->getAll());

$user = new Document();
$user->name = 'John';
$cursor = $handler->getByExample('users', $user);
var_dump($cursor->getAll());

This will return all documents from the specified collection (here: "users") with the properties provided in the example (here: that have an attribute "name" with a value of "John"). The result is a cursor which can be iterated sequentially or completely. We have chosen to get the complete result set above by calling the cursor's getAll() method. Note that getByExample() might return multiple documents if the example is ambigious.

<a name="updating_document"/a>

Updating a document

To update an existing document, the update() method of the DocumentHandler class can be used.

// update a document
$userFromServer->likes = array('fishing', 'swimming');
$userFromServer->state = 'CA';
unset($userFromServer->age);

$result = $handler->update($userFromServer);
var_dump($result);

The document that is updated using update() must have been fetched from the server before. If you want to update a document without having fetched it from the server before, use updateById():

// update a document, identified by collection and document id
$user = new Document();
$user->name = 'John';
$user->likes = array('Running', 'Rowing');

// 4818344 is the document's id
$result = $handler->updateById('users', 4818344, $user);
var_dump($result);

<a name="deleting_document"/a>

Deleting a document

To delete an existing document on the server, the delete() method of the DocumentHandler class will do. delete() just needs the document to be deleted:

// delete a document on the server, using a document object
$result = $handler->delete($userFromServer);
var_dump($result);

Note that the document must have been fetched from the server before. If you haven't fetched the document from the server before, use the deleteById() method. This requires just the collection name (here: "users") and the document id.

// delete a document on the server, using a collection id and document id
// 4818344 is the document's id
$result = $handler->deleteById('users', 4818344);
var_dump($result);

<a name="dropping_collection"/a>

Dropping a collection

To delete an existing collection on the server, use the drop() method of the CollectionHandler class. drop() just needs the name of the collection name to be dropped:

// delete a collection on the server, using it's name,
$result = $handler->drop('users');
var_dump($result);

<a name="executing_statement"/a>

Executing an AQL statement

To execute an arbitrary AQL query, use the Statement class. Executing a statement will result in a cursor, and that cursor can be used for iterating over the individual values in the result.

$statement = new Statement($connection, array("query" => "FOR e IN example RETURN e"));
$cursor = $statement->execute();
var_dump($cursor->getAll());

By default, the ArangoDB-PHP client will assume that a statement produces a list of documents and thus the cursor will try to create a document from each individual result part returned.

In the above example, the call to getAll() will produce a list of documents, and the list will contain as many documents as there were in the result.

If the result of the query is not a list of documents, this approach will fail. Here is an example query that does not produce a list of documents, but a list of scalars:

$statement = new Statement($connection, array("query" => "RETURN [ 1, 2, 3 ]"));
$cursor = $statement->execute();
var_dump($cursor->getAll()); // will fail!

When calling the getAll() method, an attempt will be made to turn 1 into a Document object, and this will end up in a fatal error.

To process such type of result, you need to explicitly specify an option when setting up the statement:

$statement = new Statement($connection, array("query" => "RETURN [ 1, 2, 3 ]"), "_flat" => true);
$cursor = $statement->execute();
var_dump($cursor->getAll()); // works!

Now the result will contain the list of scalars, without any attempts to turn them into Document objects. Here's an example query that will

<a name="alltogether"/a>

Putting it all together

Here's the full code that combines all the pieces outlined above:

// use the following line when using packagist/composer
//require dirname(__FILE__) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . '.composer' . DIRECTORY_SEPARATOR . 'autoload.php';
// use the following line when using git
require dirname(__FILE__) . DIRECTORY_SEPARATOR . 'ArangoDB-PHP' . DIRECTORY_SEPARATOR . 'autoload.php';

// set up some aliases for less typing later
use triagens\ArangoDb\Connection as ArangoConnection;
use triagens\ArangoDb\ConnectionOptions as ArangoConnectionOptions;
use triagens\ArangoDb\DocumentHandler as ArangoDocumentHandler;
use triagens\ArangoDb\Document as ArangoDocument;
use triagens\ArangoDb\Exception as ArangoException;
use triagens\ArangoDb\ConnectException as ArangoConnectException;
use triagens\ArangoDb\ClientException as ArangoClientException;
use triagens\ArangoDb\ServerException as ArangoServerException;
use triagens\ArangoDb\UpdatePolicy as ArangoUpdatePolicy;

// set up some basic connection options
$connectionOptions = array(
    ArangoConnectionOptions::OPTION_ENDPOINT => 'tcp://127.0.0.1:8529',
    // authorization type to use (currently supported: 'Basic')
    ArangoConnectionOptions::OPTION_AUTH_TYPE => 'Basic',
    // user for basic authorization
    ArangoConnectionOptions::OPTION_AUTH_USER => 'root',     
    // password for basic authorization
    ArangoConnectionOptions::OPTION_AUTH_PASSWD => '', 
    // connection persistence on server. can use either 'Close' (one-time connections) or 'Keep-Alive' (re-used connections)
    ArangoConnectionOptions::OPTION_CONNECTION => 'Close',  
    // connect timeout in seconds
    ArangoConnectionOptions::OPTION_TIMEOUT => 3,
    // optionally create new collections when inserting documents
    ArangoConnectionOptions::OPTION_CREATE => true,
    // optionally create new collections when inserting documents
    ArangoConnectionOptions::OPTION_UPDATE_POLICY => ArangoUpdatePolicy::LAST,
);

try {
    $connection = new ArangoConnection($connectionOptions);


    $collectionHandler = new CollectionHandler($connection);

    // create a new document
    $userCollection = new ArangoCollection();
	$userCollection->setName('user');
	$id = $collectionHandler->add($userCollection);

    // print the collection id created by the server
    var_dump($id);


    $handler = new ArangoDocumentHandler($connection);

    // create a new document
    $user = new ArangoDocument();

    // use set method to set document properties
    $user->set("name", "John");
    $user->set("age", 25);

    // use magic methods to set document properties
    $user->likes = array('fishing', 'hiking', 'swimming');

    // send the document to the server
    $id = $handler->add('users', $user);

    // print the document id created by the server
    var_dump($id);
    var_dump($user->getId());


    // get the document back from the server
    $userFromServer = $handler->get('users', $id);
    var_dump($userFromServer);

    // get a document list back from the server, using a document example
    $cursor = $handler->getByExample('users', array('name'=>'John'));
    var_dump($cursor->getAll());


    // update a document
    $userFromServer->likes = array('fishing', 'swimming');
    $userFromServer->state = 'CA';
    unset($userFromServer->age);

    $result = $handler->update($userFromServer);
    var_dump($result);

    // get the document back from the server
    $userFromServer = $handler->get('users', $id);
    var_dump($userFromServer);


    // delete a document on the server
    $result = $handler->delete($userFromServer);
    var_dump($result);


    // delete a collection on the server, using it's name,
    $result = $handler->drop('users');
    var_dump($result);
}
catch (ArangoConnectException $e) {
    print 'Connection error: ' . $e->getMessage() . PHP_EOL;
}
catch (ArangoClientException $e) {
    print 'Client error: ' . $e->getMessage() . PHP_EOL;
}
catch (ArangoServerException $e) {
    print 'Server error: ' . $e->getServerCode() . ':' . $e->getServerMessage() . ' ' . $e->getMessage() . PHP_EOL;
}