Google provides a Google Base extension to the Google Data API PHP Client Library that helps connect, use, and manipulate items in the Google Base Feeds. The library requires PHP 5.1.4+ and is included as a component in the Zend PHP Framework, and also available as a separate download. For help setting up the client library, see the article on Getting Started with the Google Data API PHP Client Library.
This client library is by no means the only way of connecting to and using the Google Base API. You can achieve the same results using an Atom or XML parser, or by using one of the other client libraries. If you are intersted in reading more about the underlying protocol that this library uses, see the Protocol section of this developer's guide.
Please see the PHP 4 sample application for guidance on using the API.
This document assumes that you know PHP programming, and that you are familiar with the basic concepts of Google Base.
The Google Data API PHP Client Library builds includes extensions to most Google Base-specific objects to make the service easier to use. In general, it tries to stick to the XML representation.
The XML element in a feed or entry corresponds to a single PHP object in the
library. For example, the <atom:feed> element and the
<atom:entry> element correspond to a
Zend_Gdata_Gbase_Feed and Zend_Gdata_Gbase_Entry,
respectively.
Google Base extends the Google Data feeds with elements from the
g namespace (http://base.google.com/ns-metadata/1.0)
and elements from the gm namespace
(http://base.google.com/ns/1.0). Elements in the g:
namespace correspond to an instance of the class
Zend_Gdata_Gbase_Extension_BaseAttribute. The gm: is
not currently supported with special methods in the library, although its data elements can be accessed
directly from the Zend_Gdata_Gbase_Feed object.
Note: If you have the PHP Client Library properly installed, the example code blocks in this tutorial can be cut, pasted, and run individually. They are complete examples.
As described in the
Snippets Feed reference you can
search all published items in Google Base by connecting to the snippets feed:
http://www.google.com/base/feeds/snippets
Futhermore, you can refine a search by adding paramters, attributes, and expressions to the query:
http://www.google.com/base/feeds/snippets?bq=digital+camera[item type:products][price < 150 USD]&max-results=10&orderby=modification_time
which can also be written as:
http://www.google.com/base/feeds/snippets/-/products?bq=digital+camera[price < 150 USD]&max-results=10&orderby=modification_time
To perform the same query programatically, create a new
Zend_Gdata_Gbase object, a new SnippetQuery,
and construct your query as follows:
<?php
require_once 'Zend/Loader.php'; // this should point to your Zend lib installation
Zend_Loader::loadClass('Zend_Gdata_Gbase');
$service = new Zend_Gdata_Gbase();
$query = $service->newSnippetQuery();
$query->setCategory('products');
$query->setBq('digital cameras[price < 150 USD]');
$query->setMaxResults('10');
$query->setOrderBy('modification_time');
$feed = $service->getGbaseSnippetFeed($query);
// Print our results
foreach ($feed->entries as $entry) {
echo '<p><b>' . $entry->title->text . '</b><br/>';
echo '<small>' . $entry->id->text . '</small><br/>';
echo $entry->content->text . "</p>";
}
?>
Calling $service->newSnippetQuery() instantiates a new query object
specific to the snippets feed. Each method that follows adds the respective
parameter to the search query. To verify the query is the same as the example, print
$query->getQueryUrl().
Read more about Attributes and Queries.
Read more about Query Parameters.
The Item types feed,
http://www.google.com/base/feeds/itemtypes/,
contains a list of item types recommended by Google. For each item type, it
lists the attributes that Google thinks might be useful.
Accessing the itemtypes feed using the client library is somewhat different
than with the snippets feed. Currently, there are no special accessor methods
in the client library to work with the item types feed. However, you can create an
instance of a generic Data API query with Zend_Gdata_Query class,
and specify the feed's url:
<?php
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_Gbase');
Zend_Loader::loadClass('Zend_Gdata_Query');
$service = new Zend_Gdata_Gbase();
$query = new Zend_Gdata_Query('http://www.google.com/base/feeds/itemtypes/en_US'); // don't forget to specify a locale
$query->setParam('max-results', '25');
$feed = $service->getFeed($query);
// Print our results
foreach ($feed->entries as $entry) {
$itemType = $entry->extensionElements[0]->text;
$attributesArr = $entry->extensionElements[1]->extensionElements;
echo "<p>Item type: <b>$itemType</b><br/>";
echo "<small>$entry->id->text</small><br/>";
echo '<ul>';
foreach($attributesArr as $attr) {
$name = $attr->extensionAttributes['name']['value'];
$type = $attr->extensionAttributes['type']['value'];
echo "<li>$name($type)</li>";
}
echo '</ul></p>';
}
?>
The Zend_Gdata_Query() constructor is called with the url of the itemtypes
feed and a trailing locale, in
this case en_US. To set a parameter with
Zend_Gdata_Query, use Zend_Gdata_Query::setParam().
To retrieve the feed, call Zend_Gdata_Gbase::getFeed($query) with
the Zend_Gdata_Query object you constructed (i.e. $query).
Note: Remember the data in this feed is meant as a suggestion. It is not the complete list of all item types or all attributes. The items already in Google Base may not even follow these suggestions. Additionally, you can create your own item types.
The Attributes
feed, http://www.google.com/base/feeds/attributes/, is read-only.
It provides statistics about how an item type
has been used by listing what values have been used frequently for its
attributes. This feed can also show you how others have defined the item in
existing entries. This information can be very helpful as you define new
items to upload.
You can access the attributes feed in a similar way to the itemtypes feed by
passing in the url for the attributes feed to the Zend_Gdata_Query
constructor. Since there are no special accessor methods for the attributes
feed, you have to access the properties of the returned
Zend_Gdata_Gbase_Feed directly.
The code below finds the 10 most commonly-used attributes for a digital camera and for these, the 5 most common values (for text attributes).
<?php
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_Gbase');
Zend_Loader::loadClass('Zend_Gdata_Query');
$service = new Zend_Gdata_Gbase();
$query = new Zend_Gdata_Query('http://www.google.com/base/feeds/attributes/');
$query->setParam('bq', 'digital camera');
$query->setParam('max-results', 10);
$query->setParam('max-values', 5);
$feed = $service->getFeed($query);
// Print our results
foreach ($feed->entries as $entry) {
$attribute = $entry->extensionElements[0]->extensionAttributes;
$valuesArr = $entry->extensionElements[0]->extensionElements;
echo '<p><b>' . $attribute['name']['value'] . '('. $attribute['type']['value'] . ')</b></br>';
echo 'Common values:<ul>';
foreach($valuesArr as $val) {
$count = $val->extensionAttributes['count']['value'];
$text = $val->text;
echo "<li>$text - $count times</li>";
}
echo '</ul></p>';
}
?>
Again, since the client library does not support the
gm: namespace, we constructed our query using the
Zend_Gdata_Query class and access each attribute and its common
values directly.
Note: Using the items feed requires authentication.
You can retrieve a list of all the items you have published by using the
items feed,
http://www.google.com/base/feeds/items.
Accessing the items feed using the client library can be acheived through the
Zend_Gdata_Gbase_ItemQuery class as follows:
<?php
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_Gbase');
Zend_Loader::loadClass('Zend_Gdata_Query');
$client = authenticate(); // see the Authentication section
$service = new Zend_Gdata_Gbase($client);
$query = $service->newItemQuery();
// Set parameters if you choose
$query->setBq('[title:My Great Recipe]');
$query->setOrderBy('modification_time');
$query->setCategory('Recipes');
$query->setMaxResults('5');
$feed = $service->getGbaseItemFeed($query);
foreach ($feed->entries as $entry) {
// Get all attributes and print out the name and text value of each attribute
$baseAttributes = $entry->getGbaseAttributes();
echo '<li>' . $entry->title->text . '<br/>';
foreach ($baseAttributes as $attr) {
echo 'Attribute ' . $attr->name . ' : ' . $attr->text . '<br/>';
}
echo '</li>';
}
?>
Or, you can look for a specific attribute and iterate through the results:
foreach ($feed->entries as $entry) {
// Print all main ingredients
$baseAttributes = $entry->getGbaseAttribute('main_ingredient');
echo '<li>' . $entry->title->text . '<br/>';
foreach ($baseAttributes as $attr) {
echo 'Main ingredient: ' . $attr->text . '<br/>';
}
echo '</li>';
}
After creating a new $service->newItemQuery(), set any parmeter options
using the library's special setter methods just like in the case of the
snippets feed. Finally, call
$service->getGbaseItemFeed() to return the items feed.
To insert, update, or delete items, a user must be authenticated. Depending on what type of application you are writing, there are two options: ClientLogin username/password authentication or AuthSub proxy authentication.
This scheme is intended for single-user standalone applications such as installed desktop applications. Its methods
are exposed in the Zend_Gdata_ClientLogin class. The example below uses ClientLogin to authenticate a user
by creating an Zend_Gdata_Gbase service instance.
<?php
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Gbase');
// Parameters for ClientLogin authentication
$service = Zend_Gdata_Gbase::AUTH_SERVICE_NAME;
$user = "sample.user@gmail.com";
$pass = "pa$$w0rd";
// Create an authenticated HTTP client
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
// Create an instance of the Base service
$service = new Zend_Gdata_Gbase($client);
?>
This scheme is intended for web applications to authenticate users to their Google Account. Its methods are exposed
in the Zend_Gdata_AuthSub class. A slightly different method is used in the AuthSub case.
<?php
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_Gbase');
function authenticate() {
// If there is no AuthSub session or one-time token waiting for us, redirect the user to the AuthSub server to get one.
if (!isset($_SESSION['sessionToken']) && !isset($_GET['token'])) {
// Parameters to give to AuthSub server
$next_url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$scope = 'http://www.google.com/base/feeds/items';
$secure = 0;
$session = 1;
// Redirect the user to the AuthSub server to sign in
$authSubUrl = Zend_Gdata_AuthSub::getAuthSubTokenUri($next_url, $scope, $secure, $session);
header("HTTP/1.0 307 Temporary redirect");
header("Location: " . $authSubUrl);
exit();
}
// Convert an AuthSub one-time token into a session token if needed
if (!isset($_SESSION['sessionToken']) && isset($_GET['token'])) {
$_SESSION['sessionToken'] = Zend_Gdata_AuthSub::getAuthSubSessionToken($_GET['token']);
}
// At this point we are authenticated via AuthSub and can obtain an authenticated HTTP client instance
// Create an authenticated HTTP client
$client = Zend_Gdata_AuthSub::getHttpClient($_SESSION['sessionToken']);
return $client;
}
?>
http://www.google.com/base/feeds/items.Read more about Google Account Authentication.
Note: These operations require authentication.
You can insert items into Google Base using the items feed,
http://www.google.com/base/feeds/items.
An owner can access his/her items feed to insert, update, or delete their own items. These operations do not apply to the public (read-only) snippets feed.
The full source code of an example that does much of what is
described in this section is available at /apis/base/samples/php/demo-zend.php.txt.
You can find documentation for the example in the
Sample Applications
section.
To insert an item, create the Zend_Gdata_Gbase_ItemEntry
object and add attributes:
<?php
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_Gbase');
$client = authenticate(); // see the Authentication section
$service = new Zend_Gdata_Gbase($client);
$newEntry = $service->newItemEntry();
// Add the title
$newEntry->title = $service->newTitle('My Great Recipe');
// Add the content
$newEntry->content = $service->newContent('Description goes here');
$newEntry->content->type = 'text'; // specifying a type is recommended
// Define the item type
$newEntry->itemType = 'Recipes';
$newEntry->itemType->type = 'text'; // specifying a type is recommended
// Add item-specific attributes
$newEntry->addGbaseAttribute('cuisine', 'American', 'text');
$newEntry->addGbaseAttribute('my_custom_attribute', 'NEATO', 'text');
$newEntry->addGbaseAttribute('cooking_time', '5 minutes', 'intUnit');
$newEntry->addGbaseAttribute('main_ingredient', '2 eggs', 'text');
$newEntry->addGbaseAttribute('main_ingredient', '1 cup of sugar', 'text');
$newEntry->addGbaseAttribute('serving_count', 3, 'number');
// Post the item
$dryRun = false;
$createdEntry = $service->insertGbaseItem($newEntry, $dryRun);
echo '<a href="' . $createdEntry->link[0]->href . '">View your created item in Google Base</a>';
?>
Note: You can test a feed operation before it is actually executed by
setting $dryRun=true. Once you are sure that
you want to submit the data, set it to false to execute the
operation.
Attributes can be added with
$newEntry->addGbaseAttribute($attributeName, $value, $type).
In each case, the final $type parameter is optional, but
recommended. If left off, it defaults to type text. Note, this
is different than in queries where the type is inferred from the value.
Caution: The attribute name should not contain spaces.
It is recommended that you use _ instead (i.e. item_type instead of item type).
Calling $service->insertGbaseItem publishes the item to Google Base. If
successful, it returns the item you just published as an
Zend_Gdata_Gbase_ItemEntry object, otherwise an error is returned.
$createdEntry->published->text$createdEntryId = $createdEntry->id->textThe Google Base server assigns precomputed attributes for your
entry, such as the creation date (and time), the
author and, probably most importantly, the id
(or URL) of the new entry. Keep this ID ($createdEntryId), as you
will need it to update or delete your item. You can also get this information
by running a query on the items feed and extracting the ID, but it is
recommended to store IDs.
When creating or modifying an item using the Google Base client library, keep in mind that an attribute is always identified by both its type and its name. Make sure you always specify the type when setting an attribute, as it will have an impact on which Google Base queries may be run on your items.
For example, if you set the number of
bathrooms in your "house" item
using $newEntry->addGbaseAttribute('bathrooms', '2'), Base will assume
bathrooms as type text. However, if users run the query: [bathrooms > 2] they will never get your item as an answer.
In the above example, you would need to specify a type of float
as follows: $newEntry->addGbaseAttribute('bathrooms', '2', 'float').
Make sure you choose the correct type for your attributes to get the maximum benefit from Google Base.
For Google Base queries to be really useful, it's best if people
agree on a common set of g: attributes. Google does not
constrain the attributes you can use in an item, so you might need to
be careful when choosing attribute name and types for your own items.
Read more on Recommended Attributes.
To modify a published item, you need the ID of the entry you
wish to modify. In the last step, we saved the ID of our new entry
to $createdEntryId. This ID was assigned to the item by the server.
Query the items feed using $service->newItemQuery() and retrieve the ID if you
don't previously know it.
<?php
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_Gbase');
$client = authenticate(); // see the Authentication section
$service = new Zend_Gdata_Gbase($client);
// $createdEntryId is the url (ID) of the item. See the Inserting items section
$updatedEntry = $service->getGbaseItemEntry($createdEntryId);
// Update the title
$updatedEntry->title = $service->newTitle('My Greatest Recipe');
// Update the content
$updatedEntry->content = $service->newContent('A better description');
$updatedEntry->content->type = 'text';
// Update the <g:cuisine> attribute
$baseAttributeArr = $updatedEntry->getGbaseAttribute('cuisine');
if (is_object($baseAttributeArr[0])) {
$baseAttributeArr[0]->text = 'African';
}
// Update the <g:cooking_time> attribute
$baseAttributeArr = $updatedEntry->getGbaseAttribute('cooking_time');
if (is_object($baseAttributeArr[0])) {
$baseAttributeArr[0]->text = '5 hours';
}
// Update all of the <g:main_ingredient> attributes
$baseAttributeArr = $updatedEntry->getGbaseAttribute('main_ingredient');
foreach ($baseAttributeArr as $ingredient) {
$ingredient->text = $ingredient->text . ', (update)';
}
// Remove our custom <g:my_custom_attribute> attribute
$attr = $updatedEntry->getGbaseAttribute('my_custom_attribute');
$updatedEntry->removeGbaseAttribute($attr[0]);
// Add new attribute, <g:note>
$updatedEntry->addGbaseAttribute('note', 'new note', 'text');
$dryRun = false;
$service->updateGbaseItem($updatedEntry, $dryRun);
?>
Note: Alternatively, you can use
$updatedEntry->save($dryRun) where $dryRun = false.
You might avoid reading the entry from the server if you know
exactly what your entry should look like. This is dangerous, as
updating will replace everything with the entry you specify to
updateGbaseItem(). If you forget to set an attribute that is already
in the entry, it will be removed when it is updated.
To delete an item, just call deleteGbaseItem with the entry
as the first argument. If you don't already have the entry, use
getGbaseItemEntry with the item's ID:
<?php
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_Gbase');
$client = authenticate(); // see the Authentication section
$service = new Zend_Gdata_Gbase($client);
$entry = $service->getGbaseItemEntry($createdEntryId);
$dryRun = false;
$service->deleteGbaseItem($entry, $dryRun);
?>
Note: Alternatively you can use
$entry->delete($dryRun); where $dryRun = false
The examples above do not contain any error-handling code to keep things simple.
The Zend_Gdata_Gbase methods throw exceptions which can have different
meanings depending on the concrete subclass that has been thrown,
such as Zend_Gdata_App_BadMethodCallException or Zend_Gdata_App_HttpException.
The following shows an example of very basic error handling:
try {
// make an api call
} catch (Zend_Gdata_App_HttpException $e) {
// In version 1.5+, you can enable a debug logging mode to see the
// underlying HTTP requests being made, as long as you're not using
// a proxy server. This is the recommended way to track errors.
$service->enableRequestDebugLogging('/tmp/base_requests.log');
} catch (Zend_Gdata_App_BadMethodCallException $e) {
// You can also print the message and response body directly. Do this with caution, as
it may contain sensitive data.
echo "Error: " . $e->getMessage() . "<br />\n";
if ($e->getResponse() != null) {
echo "Body: <br />\n" . $e->getResponse()->getBody() . "<br />\n";
}
}
...
For referential information about the methods in the PHP library, refer to the Google Data API Zend Framework documentation