Немалая часть моего общения с друзьями и коллегами по работе сводится к переписке по электронной почте, поэтому я привык хранить их контактные данные в адресной книге Mozilla Thunderbird - моей любимой почтовой программы. Однако в последние несколько месяцев я постепенно начал переносить контакты в Gmail, который также включает удобную адресную книгу. Этот сервис, известный под именем Google Contacts, открыт для доступа через Web, поддерживает множество информационных полей для описания контактов, а также предоставляет возможности для импорта и экспорта данных. Таким образом, он не просто позволяет сохранить всевозможную контактную информацию, но и делает ее доступной для вас в любой точке планеты, где есть компьютер и Интернет.
Сервис Google Contacts также представляет немалый интерес для разработчиков, поскольку он, как и многие сервисы Google, предоставляет API для доступа к данным, который позволяет легко создавать приложения, оперирующие информацией, хранящейся в личных адресных книгах. Этот API, созданный по принципам REST, может использоваться приложениями, написанными на любом языке, предоставляющем средства для работы с XML. Более того, на сегодняшний день уже существуют клиентские библиотеки для множества популярных языков программирования, в том числе, для моего любимого PHP.
Прочитав эту статью, вы познакомитесь с API для доступа к данным Google Contacts и увидите примеры использования контактной информации в приложении на PHP. Приведенные в статье примеры демонстрируют такие возможности, как получение списка контактов из адресной книги пользователя, добавление, удаление и редактирование контактов, а также манипулирование контактными данными, возвращаемыми в виде информационной ленты. Итак, приступим!
Интерфейс для доступа к данным Google Contacts
Перед тем как перейти непосредственно к написанию кода на PHP, необходимо сказать несколько слов об API для доступа к данным Google Contacts. Аналогично API других сервисов Google, этот интерфейс базируется на HTTP-запросах, содержащих набор представленных в XML аргументов, в ответ на которые сервер возвращает ленты Atom, включающие требуемую информацию. При этом методы API, служащие для чтения, добавления, редактирования и удаления контактов, соответствуют стандартным операциям HTTP (GET, POST, PUT и DELETE). Наконец, полученные от сервиса ленты могут обрабатываться произвольным образом в любом языке, предоставляющем средства для работы с XML.
Информационные ленты Google Contacts, как правило, содержат большой объем информации. Пример такой ленты приведен в листинге 1.
Листинг 1. Пример ленты, содержащей информацию, полученную от сервиса Google Contacts
<atom:feed xmlns:atom="http://www.w3.org/2005/Atom">
<atom:author>
<atom:name>John Doe</atom:name>
<atom:email>user@gmail.com</atom:email>
</atom:author>
<atom:category term="http://schemas.google.com/contact/2008#contact"
scheme="http://schemas.google.com/g/2005#kind"/>
<atom:id>user@gmail.com</atom:id>
<atom:link href="http://www.google.com/" rel="alternate" type="text/html"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full"
rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full"
rel="http://schemas.google.com/g/2005#post" type="application/atom+xml"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full/
batch" rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full?
max-results=25" rel="self" type="application/atom+xml"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full?
start-index=26&max-results=25" rel="next" type="application/atom+xml"/>
<atom:title type="text">John Doe's Contacts</atom:title>
<atom:updated>2009-08-31T10:48:00.410Z</atom:updated>
<atom:generator uri="http://www.google.com/m8/feeds" version="1.0">Contacts
</atom:generator>
<atom:entry xmlns:default="http://www.w3.org/2007/app"
xmlns:default1="http://schemas.google.com/g/2005"
xmlns:default2="http://schemas.google.com/contact/2008">
<default:edited xmlns="http://www.w3.org/2007/app">2009-08-22T16:52:37.457Z
</default:edited>
<default1:name xmlns="http://schemas.google.com/g/2005">
<default1:fullName>Vikram Vaswani</default1:fullName>
<default1:givenName>Vikram</default1:givenName>
<default1:familyName>Vaswani</default1:familyName>
</default1:name>
<default1:organization xmlns="http://schemas.google.com/g/2005"
rel="http://schemas.google.com/g/2005#work">
<default1:orgName>Melonfire</default1:orgName>
<default1:orgTitle>CEO</default1:orgTitle>
</default1:organization>
<default1:email xmlns="http://schemas.google.com/g/2005"
rel="http://schemas.google.com/g/2005#other" address="vikram@example.org"
primary="true"/>
<default1:email xmlns="http://schemas.google.com/g/2005"
rel="http://schemas.google.com/g/2005#home" address="vikram@example.com"/>
<default1:phoneNumber xmlns="http://schemas.google.com/g/2005"
rel="http://schemas.google.com/g/2005#mobile">0012345678901
</default1:phoneNumber>
<default1:phoneNumber xmlns="http://schemas.google.com/g/2005"
rel="http://schemas.google.com/g/2005#work_fax">0045678901234
</default1:phoneNumber>
<default2:website xmlns="http://schemas.google.com/contact/2008"
href="http://www.melonfire.com/" rel="home"/>
<default2:website xmlns="http://schemas.google.com/contact/2008"
href="http://www.php-beginners-guide.com/" rel="blog"/>
<default2:groupMembershipInfo xmlns="http://schemas.google.com/contact/2008"
deleted="false"
href="http://www.google.com/m8/feeds/groups/user%40gmail.com/base/6"/>
<atom:category term="http://schemas.google.com/contact/2008#contact"
scheme="http://schemas.google.com/g/2005#kind"/>
<atom:id>http://www.google.com/m8/feeds/contacts/user%40gmail.com/base/0
</atom:id>
<atom:link href="http://www.google.com/m8/feeds/photos/media/user%40gmail.com/0"
rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full/0"
rel="self" type="application/atom+xml"/>
<atom:link href="http://www.google.com/m8/feeds/contacts/user%40gmail.com/full/0"
rel="edit" type="application/atom+xml"/>
<atom:title type="text">Vikram Vaswani</atom:title>
<atom:updated>2009-08-22T16:52:37.457Z</atom:updated>
<atom:content type="text">PHP enthusiast</atom:content>
</atom:entry>
<atom:entry xmlns:default="http://www.w3.org/2007/app"
xmlns:default1="http://schemas.google.com/g/2005">
</atom:entry>
<openSearch:totalResults xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"
>153</openSearch:totalResults>
<openSearch:startIndex xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"
>1</openSearch:startIndex>
<openSearch:itemsPerPage xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/"
>25</openSearch:itemsPerPage>
</atom:feed>
|
Каждая лента Google Contacts включает корневой элемент <feed>. Внутри него находятся элементы <link> и <openSearch:>, содержащие ссылки (URL) на разные версии ленты и сводную статистическую информацию соответственно.
В корневом элементе <feed> находятся один или несколько элементов <entry>, каждый из которых представляет собой контактную запись. Контактные данные включают имя, название организации, должность, адреса электронной почты и страницы в Интернете, телефон, факс, ссылку на фотографию и т. д. Кроме того, каждый элемент <entry> включает два тега <link> (<link rel="self" ...> и <link rel="edit" ...>), содержащие URL для получения полной версии записи и ее редактирования соответственно.
Необходимо помнить, что ленты Google Contacts содержат личную информацию, поэтому выполнение любых операций над ними, в том числе просмотра, требуют аутентификации при помощи имени пользователя и пароля. Аутентификация может производиться одним из двух одобренных Google методов: AuthSub и ClientLogin.
Выполнение аутентификации вручную представляет собой достаточно трудоемкую задачу, требующую немалого объема кода для обработки всевозможных сценариев, которые могут произойти во время транзакции. К счастью, этого можно избежать, воспользовавшись клиентской библиотекой Zend's® GData, которая была создана специально для разработчиков PHP-приложений, желающих использовать API для доступа к данным сервисов Google (ссылка для загрузки Zend's GData приведена в разделе Ресурсы). Данная библиотека предоставляет удобный объектно-ориентированный интерфейс для работы с API сервисов Google и высокоуровневые средства для выполнения наиболее часто встречающихся задач, в частности аутентификации, позволяя, тем самым, разработчикам сконцентрироваться на функциональности своих приложений. Zend's GData будет использоваться ниже, поэтому установите ее перед тем, как переходить к выполнению примеров.
После установки библиотеки Zend's GData можно переходить к рассмотрению примеров работы с лентами Google Contacts в PHP. Пример кода, приведенный в листинге 2, разбирает ленту из листинга 1 при помощи SimpleXML, выделяя из нее требующуюся информацию для последующего форматирования и вывода на Web-страницу.
Листинг 2. Пример получения списка контактов и их отображения на странице
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Listing contacts</title>
<style>
body {
font-family: Verdana;
}
div.name {
color: red;
text-decoration: none;
font-weight: bolder;
}
div.entry {
display: inline;
float: left;
width: 400px;
height: 150px;
border: 2px solid;
margin: 10px;
padding: 5px;
}
td {
vertical-align: top;
}
</style>
</head>
<body>
<?php
// Загрузка библиотеки Zend Gdata
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// Задание учетных параметров для аутентификации через ClientLogin
$user = "user@gmail.com";
$pass = "guessme";
try {
// Выполнение аутентификации и установка версии протокола (3.0)
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// Выполнение запроса и получение ленты
$query = new Zend_Gdata_Query(
'http://www.google.com/m8/feeds/contacts/default/full');
$feed = $gdata->getFeed($query);
// Вывод заголовка и числа полученных записей
?>
<h2><?php echo $feed->title; ?></h2>
<div>
<?php echo $feed->totalResults; ?> contact(s) found.
</div>
<?php
// Разбор ленты и извлечение контактных данных
$results = array();
foreach($feed as $entry){
$xml = simplexml_load_string($entry->getXML());
$obj = new stdClass;
$obj->name = (string) $entry->title;
$obj->orgName = (string) $xml->organization->orgName;
$obj->orgTitle = (string) $xml->organization->orgTitle;
foreach ($xml->email as $e) {
$obj->emailAddress[] = (string) $e['address'];
}
foreach ($xml->phoneNumber as $p) {
$obj->phoneNumber[] = (string) $p;
}
foreach ($xml->website as $w) {
$obj->website[] = (string) $w['href'];
}
$results[] = $obj;
}
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
<?php
// Вывод результатов
foreach ($results as $r) {
?>
<div class="entry">
<div class="name"><?php echo (!empty($r->name)) ?
$r->name : 'Name not available'; ?></div>
<div class="data">
<table>
<tr>
<td>Organization</td>
<td><?php echo $r->orgName; ?></td>
</tr>
<tr>
<td>Email</td>
<td><?php echo @join(', ', $r->emailAddress); ?></td>
</tr>
<tr>
<td>Phone</td>
<td><?php echo @join(', ', $r->phoneNumber); ?></td>
</tr>
<tr>
<td>Web</td>
<td><?php echo @join(', ', $r->website); ?></td>
</tr>
</table>
</div>
</div>
<?php
}
?>
</body>
</html>
|
Результат показан на рисунке 1 (адрес личной электронной почты был сознательно стерт).
Рисунок 1. Web-страница со списком контактов
В листинге 2 сначала загружаются библиотеки классов Zend, а затем инициализируется экземпляр класса-сервиса Zend_Gdata. Данный класс использует объект Zend_Http_Client для установки аутентифицированного соединения с Google Contacts, передавая ему учетные данные пользователя. Сразу после открытия соединения выполняется вызов метода getFeed() для получения ленты, содержащей контактную информацию. Этот метод принимает в качестве аргумента объект Zend_Gdata_Query, в котором содержится URL ленты. Также следует обратить внимание на вызов метода setMajorProtocolVersion(), который указывает серверу, что следует использовать API 3.0 для доступа к Google Contacts. В данном случае этот вызов необходим, и его отсутствие может привести к неожиданным последствиям.
Метод getFeed() возвращает ленту в формате XML, аналогичную показанной в листинге 1, которая затем разбирается и представляется в виде объекта PHP. При этом записи ленты оказываются представленными в виде элементов массива, который можно обходить в цикле, получая тем самым доступ к контактным данным. Простейший способ выборки нужных данных из XML заключается в применении SimpleXML, поэтому в данном примере используется метод simplexml_load_string(), который преобразует элементы, содержащие контактные записи, в объекты SimpleXML. Далее выбираются дочерние элементы каждого тега <entry>, которые затем объединяются в единый объект, после чего все подобные объекты сохраняются в массиве $results. После окончания выборки всех записей ленты можно легко обойти все элементы этого массива при помощи оператора foreach(), преобразовав их к виду, подходящему для вывода на Web-страницу.
Необходимо сказать несколько слов об URL внутри объекта Zend_Gdata_Query. Этот адрес был сформирован в соответствии с форматом http://www.google.com/m8/feeds/contacts/USERID/TYPE, т. е. путем добавления имени пользователя и типа ленты к стандартному URL ленты. Существует два типа лент: полный и сокращенный (в последнем случае сервис возвращает только часть контактных данных). Если, как в листинге 2, указать ключевое слово default вместо имени, то будет получена лента по умолчанию для текущего пользователя.
Разобравшись с получением контактной информации, возникает естественный вопрос: а как добавлять новые контакты?
Эта задача решается проще, чем можно было бы предположить. Для добавления нового контакта достаточно отправить запрос типа POST, в теле которого содержится представленный в XML фрагмент <entry>, по адресу, соответствующему URL ленты. Пример такого фрагмента приведен в листинге 3.
Листинг 3. Пример контактной записи Google Contacts
<?xml version="1.0"?>
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:gd="http://schemas.google.com/g/2005">
<gd:name>
<gd:fullName>Jack Frost</gd:fullName>
</gd:name>
<gd:email address="jack.frost@example.com"
rel="http://schemas.google.com/g/2005#home"/>
<gd:organization rel="http://schemas.google.com/g/2005#work">
<gd:orgName>Winter Inc.</gd:orgName>
</gd:organization>
</atom:entry>
|
Библиотека Zend позволяет еще более упростить добавление контактов. Все, что от вас требуется – это вызвать метод insertEntry(), который создает запрос типа POST и передает данные по указанному URL ленты. Пример приведен в листинге 4.
Листинг 4. Пример добавления новой контактной записи
<?php
// Загрузка библиотеки Zend Gdata
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// Задание учетных параметров для аутентификации методом ClientLogin
$user = "user@gmail.com";
$pass = "guessme";
try {
// Аутентификация и установка версии протокола (3.0)
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// Создание новой записи
$doc = new DOMDocument();
$doc->formatOutput = true;
$entry = $doc->createElement('atom:entry');
$entry->setAttributeNS('http://www.w3.org/2000/xmlns/' ,
'xmlns:atom', 'http://www.w3.org/2005/Atom');
$entry->setAttributeNS('http://www.w3.org/2000/xmlns/' ,
'xmlns:gd', 'http://schemas.google.com/g/2005');
$doc->appendChild($entry);
// Добавление имени
$name = $doc->createElement('gd:name');
$entry->appendChild($name);
$fullName = $doc->createElement('gd:fullName', 'Jack Frost');
$name->appendChild($fullName);
// Добавление адреса электронной почты
$email = $doc->createElement('gd:email');
$email->setAttribute('address' ,'jack.frost@example.com');
$email->setAttribute('rel' ,'http://schemas.google.com/g/2005#home');
$entry->appendChild($email);
// Добавление названия организации
$org = $doc->createElement('gd:organization');
$org->setAttribute('rel' ,'http://schemas.google.com/g/2005#work');
$entry->appendChild($org);
$orgName = $doc->createElement('gd:orgName', 'Winter Inc.');
$org->appendChild($orgName);
// Вставка записи
$entryResult = $gdata->insertEntry($doc->saveXML(),
'http://www.google.com/m8/feeds/contacts/default/full');
echo '<h2>Add Contact</h2>';
echo 'The ID of the new entry is: ' . $entryResult->id;
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
|
В листинге 4 показан пример открытия аутентифицированного соединения с API сервиса Google Contacts через объект Zend_Gdata, который ранее использовался в листинге 2. Далее происходит динамическое формирование фрагмента <entry>, приведенного выше в листинге 3, при помощи расширения DOM в PHP. Наконец, вызов метода insertEntry() приводит к сохранению сформированного фрагмента на одном из серверов Google. Добавленная запись сразу же становится доступной через Web-интерфейс Google Contacts.
Обратите внимание, что вы можете отметить адреса e-mail и телефоны как "домашний", "рабочий" или "мобильный", выбрав соответствующую схему для элемента <gd:organization rel="..." />.
После добавления записи Web-страница должна принять вид как на рисунке 2.
Рисунок 2. Результат добавления новой контактной записи
Некоторые части подтверждающего сообщения Google были умышленно стерты. Само сообщение представлено в следующем формате: Добавленная запись имеет идентификатор http://www.google.com/m8/feeds/contacts/USER_ID/base/CONTACT_ID.
При просмотре через Web-интерфейс Google Contacts добавленная запись выглядит как на рисунке 3.
Рисунок 3. Просмотр добавленной контактной записи через Web-интерфейс Gmail
Удаление и редактирование контактов
API для доступа к данным Google Contacts также предоставляет возможности для удаления и редактирования контактных записей. Для удаления следует отправить запрос типа DELETE по адресу, соответствующему URL записи (он указан в элементе <link rel="edit" ...>). Если вы используете библиотеку Zend, то достаточно просто передать этот URL методу delete() объекта Zend_Gdata, как показано в листинге 5.
Листинг 5. Пример удаления контактных данных
<?php
// Загрузка библиотеки Zend Gdata
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// Задание учетных параметров для аутентификации методом ClientLogin
$user = "user@gmail.com";
$pass = "guessme";
// Задание идентификатора удаляемой записи
// from <link rel=edit>
$id = 'http://www.google.com/m8/feeds/contacts/default/base/29e98jf648c495c7b';
try {
// Аутентификация и установка версии протокола (3.0)
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$client->setHeaders('If-Match: *');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// Удаление контактных данных
$gdata->delete($id);
echo '<h2>Delete Contact</h2>';
echo 'Entry deleted';
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
|
Для редактирования следует сначала получить содержимое записи методом getEntry(), изменить нужные поля, а затем сохранить изменения на сервере при помощи метода updateEntry() объекта Zend_Gdata. Данный объект самостоятельно отправит запрос типа PUT по URL, указанному в элементе <link rel="self" ...> записи. Пример изменения имени и адреса e-mail в контактной записи показан в листинге 6.
Листинг 6. Редактирование контактных данных
<?php
// Загрузка библиотеки Zend Gdata
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// Задание учетных параметров для аутентификации методом ClientLogin
$user = "user@gmail.com";
$pass = "guessme";
// Задание идентификатора редактируемой записи
// from <link rel=self>
$id = 'http://www.google.com/m8/feeds/contacts/default/full/0';
try {
// Аутентификация и установка версии протокола (3.0)
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$client->setHeaders('If-Match: *');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// Выполнение запроса и получение записи
$query = new Zend_Gdata_Query($id);
$entry = $gdata->getEntry($query);
$xml = simplexml_load_string($entry->getXML());
// Изменение имени
$xml->name->fullName = 'John Rabbit';
// Изменение основного адреса электронной почты
foreach ($xml->email as $email) {
if (isset($email['primary'])) {
$email['address'] = 'jr@example.com';
}
}
// Обновление записи
$entryResult = $gdata->updateEntry($xml->saveXML(),
$entry->getEditLink()->href);
echo 'Entry updated';
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
|
Обратите внимание на поле "If-Match" в заголовках HTTP-запросов в листингах 5 и 6. Это поле особенно полезно в многопользовательской среде, поскольку оно позволяет выполнять операцию удаления или обновления только в том случае, если запись не была изменена с момента последнего чтения. Использование этого поля описывается более подробно в руководстве разработчика по использованию API для доступа к данным Google Contacts (ссылка приведена в разделе Ресурсы).
Использование дополнительных параметров
API для доступа к Google Contacts поддерживает несколько дополнительных параметров, влияющих на чтение лент, содержащих контактную информацию:
- параметр
start-indexуказывает, начиная с какого порядкового номера записи должны включаться в ленту; - параметр
max-resultsзадает число записей в ленте; - при помощи параметров
orderbyиsortorderзадаются способ и направление упорядочивания записей в ленте; - параметр
showdeletedуказывает, следует ли включать в ленту записи, удаленные за последние 30 дней.
При использовании библиотеки Zend значения многих из этих параметров можно устанавливать через соответствующие свойства объекта Zend_Gdata_Query. Кроме того, данный объект содержит метод setParam(), служащий для работы с параметрами, специфичными для конкретного сервиса Google. Оба способа иллюстрируются в листинге 7, в котором длина ленты ограничивается 10 записями, упорядоченными по убыванию даты последнего редактирования.
Листинг 7. Пример использования дополнительных параметров при выполнении запроса
<?php
// Загрузка библиотеки Zend Gdata
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// Задание учетных параметров для аутентификации методом ClientLogin
$user = "user@gmail.com";
$pass = "guessme";
try {
// Аутентификация и установка версии протокола (3.0)
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// Выполнение запроса и получение ленты
$query = new Zend_Gdata_Query(
'http://www.google.com/m8/feeds/contacts/default/full');
$query->maxResults = 10;
$query->setParam('orderby', 'lastmodified');
$query->setParam('sortorder', 'descending');
$feed = $gdata->getFeed($query);
// Вывод заголовка и числа записей в ленте
// остальной код опущен для краткости...
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
|
Теперь, когда вы уже имеет представление о работе с API для доступа к Google Contacts, пришло время создать простое приложение на PHP, позволяющее добавлять и редактировать контакты. Прототип данного приложения содержит следующие три страницы (ссылка на zip-архив с исходным кодом приведена в разделе Загрузка):
- contacts-index.php выводит список контактов, а также содержит ссылки для добавления и удаления записей;
- contacts-save.php отображает форму добавления новой записи и обрабатывает отправленные через нее данные;
- contacts-delete.php удаляет указанную запись.
Вначале мы рассмотрим первую страницу, представляющую собой модифицированный вариант листинга 2, в который было добавлено несколько ссылок (листинг 8).
Листинг 8. Получение и отображение списка контактов
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Listing contacts</title>
<style>
body {
font-family: Verdana;
}
div.name {
color: red;
text-decoration: none;
font-weight: bolder;
}
div.entry {
display: inline;
float: left;
width: 450px;
height: 150px;
border: 2px solid;
margin: 10px;
padding: 5px;
}
td {
vertical-align: top;
}
span.links {
float: right;
}
</style>
</head>
<body>
<h2>Contacts</h2>
<?php
// Загрузка библиотеки Zend Gdata
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// Задание учетных параметров для аутентификации методом ClientLogin
$user = "user@gmail.com";
$pass = "guessme";
try {
// Аутентификация и установка версии протокола (3.0)
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// Выполнение запроса и получение ленты с контактными данными
$query = new Zend_Gdata_Query(
'http://www.google.com/m8/feeds/contacts/default/full');
$query->maxResults = 0;
$query->setParam('orderby', 'lastmodified');
$query->setParam('sortorder', 'descending');
$feed = $gdata->getFeed($query);
// Отображение числа контактных записей в ленте
?>
<h2><?php echo $feed->title; ?></h2>
<div>
<?php echo $feed->totalResults; ?> contact(s) found.
</div>
<?php
// Разбор ленты и представление контактных записей
// в виде массива простых объектов
$results = array();
foreach($feed as $entry){
$obj = new stdClass;
$obj->edit = $entry->getEditLink()->href;
$xml = simplexml_load_string($entry->getXML());
$obj->name = (string) $entry->title;
$obj->orgName = (string) $xml->organization->orgName;
$obj->orgTitle = (string) $xml->organization->orgTitle;
foreach ($xml->email as $e) {
$obj->emailAddress[] = (string) $e['address'];
}
foreach ($xml->phoneNumber as $p) {
$obj->phoneNumber[] = (string) $p;
}
foreach ($xml->website as $w) {
$obj->website[] = (string) $w['href'];
}
$results[] = $obj;
}
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
<div>
<a href="contacts-save.php">Add a new contact</a>
</div>
<?php
// Вывод результатов
foreach ($results as $r) {
?>
<div class="entry">
<div class="name"><?php echo (!empty($r->name))
? $r->name : 'Name not available'; ?>
<span class="links"><a href="contacts-delete.php?
id=<?php echo $r->edit; ?>">Delete</a></span>
</div>
<div class="data">
<table>
<tr>
<td>Organization:</td>
<td><?php echo $r->orgName; ?></td>
</tr>
<tr>
<td>Email:</td>
<td><?php echo @join(', ', $r->emailAddress); ?></td>
</tr>
<tr>
<td>Phone:</td>
<td><?php echo @join(', ', $r->phoneNumber); ?></td>
</tr>
<tr>
<td>Web:</td>
<td><?php echo @join(', ', $r->website); ?></td>
</tr>
</table>
</div>
</div>
<?php
}
?>
</body>
</html>
|
Внешний вид страницы показан на рисунке 4.
Рисунок 4. Внешний вид страницы для отображения контактных данных со ссылками для удаления и добавления
Как видно из рисунка 4, каждая запись теперь включает ссылку для удаления. URL ссылки содержит идентификатор записи, который передается сервису в виде параметра GET-запроса. Серверный скрипт получает данный идентификатор и удаляет запись методом, продемонстрированным в листинге 5. Пример кода приведен в листинге 9.
Листинг 9. Удаление контактных данных
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Deleting contacts</title>
</head>
<body>
<h2>Delete Contact</h2>
<?php
// Загрузка библиотеки Zend Gdata
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// Задание учетных параметров для аутентификации методом ClientLogin
$user = "user@gmail.com";
$pass = "guessme";
if (empty($_GET['id'])) {
die('ERROR: Missing ID');
}
try {
// Аутентификация и установка версии протокола (3.0)
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
// Задание значения поля If-Match в заголовке HTTP
$client->setHeaders('If-Match: *');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// Удаление записи
$gdata->delete($_GET['id']);
echo 'Entry deleted';
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
?>
</body>
</html>
|
Выше были приведены примеры получения списка записей и их удаления. Что касается добавления, то обратите внимание на листинг 10, в котором показан серверный скрипт, позволяющий создавать записи через Web-форму. Данный скрипт использует библиотеку Zend для формирования и отправки запроса типа POST для сохранения записи на сервере.
Листинг 10. Добавление новых контактных данных
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Adding new contacts</title>
<style>
body {
font-family: Verdana;
}
</style>
</head>
<body>
<h2>Add Contact</h2>
<?php if (!isset($_POST['submit'])) { ?>
<form method="post"
action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
Name: <br/>
<input name="name" type="text" size="15" /><p/>
Email address(es): <br/>
<textarea name="email" type="text"></textarea><p/>
Organization: <br/>
<input name="org" type="text" size="15" /><p/>
<input name="submit" type="submit" value="Save" />
</form>
<?php
} else {
// Проверка наличия необходимых входных данных
if (empty($_POST['name'])) {
die('ERROR: Missing name');
}
if (empty($_POST['email'])) {
die('ERROR: Missing email address');
}
if (empty($_POST['org'])) {
die('ERROR: Missing organization');
}
// Первичная обработка ввода и сохранение информации в массиве
$inputData['name'] = htmlentities($_POST['name']);
$inputData['email'] = htmlentities($_POST['email']);
$inputData['org'] = htmlentities($_POST['org']);
// Загрузка библиотеки Zend Gdata
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Http_Client');
Zend_Loader::loadClass('Zend_Gdata_Query');
Zend_Loader::loadClass('Zend_Gdata_Feed');
// Задание учетных параметров для аутентификации методом ClientLogin
$user = "user@gmail.com";
$pass = "guessme";
try {
// Аутентификация и установка версии протокола (3.0)
$client = Zend_Gdata_ClientLogin::getHttpClient(
$user, $pass, 'cp');
$gdata = new Zend_Gdata($client);
$gdata->setMajorProtocolVersion(3);
// Создание новой записи
$doc = new DOMDocument();
$doc->formatOutput = true;
$entry = $doc->createElement('atom:entry');
$entry->setAttributeNS('http://www.w3.org/2000/xmlns/' ,
'xmlns:atom', 'http://www.w3.org/2005/Atom');
$entry->setAttributeNS('http://www.w3.org/2000/xmlns/' ,
'xmlns:gd', 'http://schemas.google.com/g/2005');
$doc->appendChild($entry);
// Добавление имени
$name = $doc->createElement('gd:name');
$entry->appendChild($name);
$fullName = $doc->createElement('gd:fullName', $inputData['name']);
$name->appendChild($fullName);
// Добавление адресов электронной почты
$arr = explode(',', $inputData['email']);
foreach ($arr as $a) {
$email = $doc->createElement('gd:email');
$email->setAttribute('address', $a);
$email->setAttribute('rel' ,'http://schemas.google.com/g/2005#work');
$entry->appendChild($email);
}
// Добавление названия организации
$org = $doc->createElement('gd:organization');
$org->setAttribute('rel' ,'http://schemas.google.com/g/2005#work');
$entry->appendChild($org);
$orgName = $doc->createElement('gd:orgName', $inputData['org']);
$org->appendChild($orgName);
// Вставка записи
$entryResult = $gdata->insertEntry($doc->saveXML(),
'http://www.google.com/m8/feeds/contacts/default/full');
echo 'The ID of the new entry is: ' . $entryResult->id;
} catch (Exception $e) {
die('ERROR:' . $e->getMessage());
}
}
?>
</body>
</html>
|
Листинг 10 состоит из двух частей: Web-формы и кода на PHP, который обрабатывает полученные от пользователя данные. Внешний вид Web-формы показан на рисунке 5.
Рисунок 5. Внешний вид Web-формы для добавления контактных данных
После того как пользователь ввел имя, адрес электронной почты, название организации и отправил форму, ее содержимое передается на обработку второй части скрипта. В ней инициализируется клиентский объект HTTP, с помощью которого открывается аутентифицированное соединение с API сервиса Google Contacts. Затем выполняется проверка данных формы, после чего они помещаются в только что созданный экземпляр DOMDocument.
Далее новый элемент <entry> создается динамически средствами DOM в PHP, а затем вызывается метод insertEntry(), отвечающий за сохранение записи на сервере Google. После сохранения записи API возвращает ее уникальный идентификатор, который показывается пользователю, говоря о том, что новый контакт был успешно добавлен.
После добавления контакта страница примет вид как на рисунке 6.
Рисунок 6. Внешний вид страницы после добавления новой контактной записи
Некоторые поля в подтверждающем сообщении, показанном на рисунке 6, были умышленно стерты. Само сообщение выдается в формате: Добавленная запись имеет идентификатор http://www.google.com/m8/feeds/contacts/USER_ID/base/CONTACT_ID
Итак, вы прошли краткий курс по использованию API для доступа к сервису Google Contacts в приложениях на PHP при помощи SimpleXML и клиентской библиотеки Zend. На приведенных примерах вы познакомились с форматом информационных лент Google Contacts, получением списка контактов, а также их удалением, добавлением и редактированием. Кроме того, вы увидели, как можно создать собственное Web-приложение для отображения контактов, хранящихся в вашей учетной записи Google.
Как видно из примеров, API для доступа к Google Contacts предоставляет разработчикам широкие возможности по созданию новых приложений для управления списком контактов. Попробуйте его в деле, чтобы составить собственное мнение!
| Описание | Имя | Размер | Метод загрузки |
|---|---|---|---|
| Исходный код последнего примера | contacts-example-app.zip | 4 KБ | HTTP |
Научиться
- Оригинал статьи: Integrate your PHP application with Google Contacts (Викрам Васвани, developerWorks, сентябрь 2009 г.). (EN)
- Узнайте больше об API для доступа к Google Contacts, прочитав руководство разработчика и справочник. (EN)
- Более подробную информацию о классах Zend Gdata можно получить из руководства по Zend Framework. (EN)
- Вопросы, касающиеся программного использования сервиса Google Contacts, можно обсудить на официальном форуме Google Contacts Data API. (EN)
- Узнать о новостях, касающихся программных интерфейсов Google, можно в блоге Google Data API. (EN)
- Узнайте больше о разработке приложений, использующих другие сервисы Google, в том числе YouTube, Picasa и Google Notebook, прочитав следующие статьи:
- Использование API YouTube в приложениях на PHP (Викрам Васвани, developerWorks, апрель 2009 г.). Данная статья рассказывает о способах обработки и интеграции данных, полученных от сервиса Youtube, в PHP-приложения при помощи расширения SimpleXML. (EN)
- Использование Web-альбомов Picasa в PHP-приложениях (Викрам Васвани, developerWorks, сентябрь 2008 г.). Темой этой статьи является интеграция Web-альбомов Picasa в PHP-приложения. (EN)
- Использование и интеграция данных Google Notebook в PHP-приложения (Викрам Васвани, developerWorks, май 2008 г.). Из этой статьи вы узнаете об использовании REST-интерфейсов для доступа к Google Notebook при создании клиентских PHP-приложений. (EN)
-
Сертификация по XML корпорации IBM: узнайте, как стать сертифицированным разработчиком IBM в области XML и связанных с ним технологий. (EN)
- Обратитесь к магазину технической литературы, в котором представлены книги на данную и другие темы. (EN)
- Слушайте интервью и обсуждения вопросов, интересующих разработчиков программного обеспечения, в трансляциях developerWorks. (EN)
Получить продукты и технологии
- Загрузите библиотеку Zend GData, предоставляющую все необходимые средства для доступа к данным Google Contacts из приложений, написанных на PHP 5. (EN)
Викрам Васвани (Vikram Vaswani) – основатель и президент консалтинговой фирмы Melonfire, специализирующейся на технологиях и инструментах с открытым исходным кодом. Также является автором книг Решения по программированию на PHP and Как сделать все что угодно с помощью PHP и MySQL .