通讯录php_将您PHP应用程序与Google通讯录集成

通讯录php

由于我与朋友和同事的大部分交流都是通过电子邮件进行的,因此我已经习惯于将联系信息存储在我的默认电子邮件客户端Mozilla Thunderbird附带的通讯录应用程序中。 但是,在过去的几个月中,我逐渐将信息移至Gmail,而Gmail本身具有强大的通讯录。 此功能称为Google联系人,可以通过Web轻松访问,支持大量信息字段,并且具有导入和导出功能。 这样一来,不仅可以在联系人上存储全面的数据,而且可以使联系人信息在各个位置之间“旅行”,因为您可以从任何可通过Web访问的计算机上访问它。

从开发的角度来看,Google通讯录也很有趣:与许多其他Google产品一样,它公开了一个Data API,使开发人员可以轻松地围绕私有地址簿中存储的数据构建新的应用程序。 该API遵循REST模型,可以通过任何支持XML的开发工具包进行访问,并且已经具有许多常用编程语言的客户端库,包括我最喜欢PHP。

本文将向您介绍Google Contacts Data API,并向您展示如何与自定义PHP应用程序集成和使用联系人数据。 在示例中,您将从用户的通讯簿中检索联系人,添加新联系人,修改和删除联系人,以及控制联系人供稿中返回的数据。 快来吧,让我们开始吧!

了解Google联系人API

在深入研究PHP代码之前,请先对Google Contacts Data API进行一些说明。 与其他Google Data API一样,系统会接受包含一个或多个XML编码输入参数的HTTP请求,并返回包含所请求信息的Atom提要。 然后可以使用任何支持XML的编程语言来解析这些提要。 此外,GET,POST,PUT和DELETE的标准HTTP操作已映射到分别检索,添加,更新和删除记录的API方法。

典型的Google Contacts feed中包含很多信息。 考虑清单1中的示例:

清单1:一个示例Google Contacts feed
<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>

每个联系人供稿均以<feed>元素作为根元素打开。 <feed>元素包含<link>元素和<openSearch:>元素,其中<link>元素包含供稿的不同版本的URL,而<openSearch:>元素包含摘要统计信息。

最外面的<feed>元素包含一个或多个<entry>元素,每个元素代表一个接触。 每个<entry>包含更多详细信息,包括联系人的姓名,组织,职务,电子邮件地址,电话和传真号码,网站和照片(除其他外)。 每个<entry>还包含另外两个<link>元素: <link rel="self" ...><link rel="edit" ...> ,它们包含用于检索完整条目和编辑URL的URL。条目。

检索联系人

请务必注意,Google通讯录供稿是私有的。 这意味着,仅对提要中包含的数据执行任何操作(包括仅对其进行查看),只有使用Google批准的两种身份验证方法之一AuthSub或ClientLogin使用提要所有者的用户名和密码对操作进行了身份验证后,该操作才能成功。

手动执行这种类型的身份验证是一件非常麻烦的事情,并且需要大量的代码来说明在典型的身份验证事务期间可能出现的各种情况。 幸运的是,您不必为此担心太多:Zend's®GData Client Library专为将PHP应用程序与Google Data API集成在一起的开发人员而设计,可以为您处理所有详细信息。 您可以单独下载该库(请参阅参考资料中的链接),它提供了一个方便的,面向对象的Google Data API界面,封装了最常见的任务(包括身份验证),使您可以专注于核心您的应用程序的功能。 本文中的其余示例将利用此库,因此在继续操作之前,请确保已安装该库。

安装Zend的GData库后,我们来看一个使用PHP处理Google Contacts Data API提要的示例。 清单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
    // load Zend Gdata libraries
    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');
    
    // set credentials for ClientLogin authentication
    $user = "user@gmail.com";
    $pass = "guessme";
    
    try {
      // perform login and set protocol version to 3.0
      $client = Zend_Gdata_ClientLogin::getHttpClient(
        $user, $pass, 'cp');
      $gdata = new Zend_Gdata($client);
      $gdata->setMajorProtocolVersion(3);
      
      // perform query and get result feed
      $query = new Zend_Gdata_Query(
        'http://www.google.com/m8/feeds/contacts/default/full');
      $feed = $gdata->getFeed($query);
      
      // display title and result count
      ?>
      
      <h2><?php echo $feed->title; ?></h2>
      <div>
      <?php echo $feed->totalResults; ?> contact(s) found.
      </div>
      
      <?php
      // parse feed and extract contact information
      // into simpler objects
      $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
    // display results
    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.列出联系人的网页
列出联系人的网页的屏幕截图

首先清单2加载Zend类库,然后初始化Zend_Gdata服务类的实例。 此类使用Zend_Http_Client对象,该对象提供了必要的用户身份验证信息,并用于打开与Google Contacts服务的身份验证连接。 打开经过身份验证的连接后, getFeed()方法将检索联系人供稿。 此方法接受Zend_Gdata_Query对象,该对象已通过Feed URL传递。 还要注意清单2中setMajorProtocolVersion()的调用,该调用告诉服务器使用v3.0的Google Contacts Data API。 这是必需的电话。 如果您忽略它,则可能会看到意外的行为。

getFeed() API调用的响应是类似于清单1的XML提要,然后将其解析并转换为PHP对象。 提要中的条目表示为数组元素,从而可以遍历提要并检索单个联系人条目。 由于SimpleXML提供了一种从XML树中检索特定信息的简便方法,因此使用simplexml_load_string()方法将每个条目的XML转换为SimpleXML对象。 然后,检索每个<entry>下的子节点并将其展平为一个更简单的对象,以方便检索,然后将每个结果对象放入$results数组中。 处理完整个提要后,您可以使用foreach()循环轻松地遍历$results数组,并格式化内容以在Web浏览器中显示。

关于传递给Zend_Gdata_Query对象的提要URL,这里有几句话:它是通过将用户名和提要类型附加到标准提要URL中而生成的,位于http://www.google.com/m8/feeds/contacts/USERID/类型。 饲料类型分为全饲料和稀饲料两种,后者仅返回整个条目的一部分。 并使用特殊关键字default代替用户名,如清单2所示 ,返回用户的默认feed。

新增联络人

这样就可以列出联系人。 现在,如何添加新联系人?

实际上,这并不像看起来那样复杂。 要添加新联系人,只需将一个新的XML编码的<entry>块发布到feed 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
// load Zend Gdata libraries
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');

// set credentials for ClientLogin authentication
$user = "user@gmail.com";
$pass = "guessme";

try {
  // perform login and set protocol version to 3.0
  $client = Zend_Gdata_ClientLogin::getHttpClient(
    $user, $pass, 'cp');
  $gdata = new Zend_Gdata($client);
  $gdata->setMajorProtocolVersion(3);
  
  // create new entry
  $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);
  
  // add name element
  $name = $doc->createElement('gd:name');
  $entry->appendChild($name);
  $fullName = $doc->createElement('gd:fullName', 'Jack Frost');
  $name->appendChild($fullName);
  
  // add email element
  $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);
  
  // add org name element
  $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);
  
  // insert entry
  $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使用Zend_Gdata对象打开了到Google Contacts Data API的经过身份验证的连接,如清单2所示 。 接下来,PHP中的DOM扩展会动态构造清单3中所示的XML <entry> ,并且insertEntry()方法用于将生成的XML实际保存到Google服务器。 添加条目后,该条目应立即在Google联系人界面中显示。

请注意,您可以通过在<gd:organization rel="..." />元素中指定适当的架构,将电子邮件地址和电话号码明确标记为属于“家庭”,“工作”或“移动”。

图2显示了成功添加新联系人条目后的输出:

图2.添加新联系人后的输出
添加新联系人后输出的屏幕截图

在图2的屏幕截图中,Google的确认消息中掩盖了某些字段。 该消息的格式为: The ID of the new entry is http://www.google.com/m8/feeds/contacts/USER_ID/base/CONTACT_ID.

图3显示了它在Google联系人界面中的外观:

图3. Gmail中新添加的联系人
Gmail中新添加的联系人Jack Frost的屏幕截图

删除和更新联系人

Google Contacts Data API还允许您编辑和删除条目。 要删除条目,请将DELETE请求发送到联系人的编辑URL,该URL是条目的<link rel="edit" ...>元素中指定的URL。 在Zend库上下文中,您可以简单地将此URL传递给Zend_Gdata对象的delete()方法,如清单5所示

清单5:删除联系人
<?php
// load Zend Gdata libraries
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');

// set credentials for ClientLogin authentication
$user = "user@gmail.com";
$pass = "guessme";

// set ID of entry to delete
// from <link rel=edit>
$id = 'http://www.google.com/m8/feeds/contacts/default/base/29e98jf648c495c7b';

try {
  // perform login and set protocol version to 3.0
  $client = Zend_Gdata_ClientLogin::getHttpClient(
    $user, $pass, 'cp');
  $client->setHeaders('If-Match: *');
  $gdata = new Zend_Gdata($client);
  $gdata->setMajorProtocolVersion(3);
  
  // delete entry
  $gdata->delete($id);
  echo '<h2>Delete Contact</h2>';
  echo 'Entry deleted';
} catch (Exception $e) {
  die('ERROR:' . $e->getMessage());
}
?>

要编辑条目,请使用getEntry()方法使用其唯一标识符检索条目,并更改要更新的值。 然后使用Zend_Gdata对象的updateEntry()方法将条目保存回服务器,该方法将PUT请求发送到条目的<link rel="self" ...>元素中指定的URL。 清单6演示了为联系人条目设置新名称和电子邮件地址的过程:

清单6:修改联系人
<?php
// load Zend Gdata libraries
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');

// set credentials for ClientLogin authentication
$user = "user@gmail.com";
$pass = "guessme";

// set ID of entry to update
// from <link rel=self>
$id = 'http://www.google.com/m8/feeds/contacts/default/full/0';

try {
  // perform login and set protocol version to 3.0
  $client = Zend_Gdata_ClientLogin::getHttpClient(
    $user, $pass, 'cp');
  $client->setHeaders('If-Match: *');

  $gdata = new Zend_Gdata($client);
  $gdata->setMajorProtocolVersion(3);
  
  // perform query and get entry
  $query = new Zend_Gdata_Query($id);
  $entry = $gdata->getEntry($query);
  $xml = simplexml_load_string($entry->getXML());

  // change name
  $xml->name->fullName = 'John Rabbit';
  
  // change primary email address  
  foreach ($xml->email as $email) {
    if (isset($email['primary'])) {
      $email['address'] = 'jr@example.com';  
    }  
  }
  
  // update entry
  $entryResult = $gdata->updateEntry($xml->saveXML(), 
   $entry->getEditLink()->href);
  echo 'Entry updated';
} catch (Exception $e) {
  die('ERROR:' . $e->getMessage());
}
?>

请注意, 清单5清单6都添加了一个额外的“ If-Match”标头作为HTTP请求的一部分。 此标头在多客户端环境中特别有用,因为只有在自上次读取以来尚未对其进行过更改的情况下,才可以使用该标头删除或更新该标头。 《 Google Contacts Data API开发人员指南》(请参阅参考资料中的链接)更详细地讨论了此标头。

使用其他参数

Google Contacts Data API还支持许多其他参数,可用于控制结果供稿。 以下是清单:

  • start-index参数指定供稿的起始偏移量
  • max-results参数指定提要中的条目数
  • orderbysortorder参数指定如何对提要条目进行排序
  • showdeleted参数包括提要中最近30天删除的条目

如果使用Zend客户端库,则只需设置Zend_Gdata_Query对象的相应属性即可设置许多这些参数。 对于特定于服务的那些参数,Zend_Gdata_Query对象还提供了setParam()方法。 清单7中说明了这两种技术,该技术将结果集限制为10个条目,并按其最后修改日期的降序排列。

清单7:设置其他查询参数
<?php
// load Zend Gdata libraries
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');

// set credentials for ClientLogin authentication
$user = "user@gmail.com";
$pass = "guessme";

try {
  // perform login and set protocol version to 3.0
  $client = Zend_Gdata_ClientLogin::getHttpClient(
    $user, $pass, 'cp');
  $gdata = new Zend_Gdata($client);
  $gdata->setMajorProtocolVersion(3);
  
  // perform query and get result feed
  $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);

  // display title and result count
  // snip...
} catch (Exception $e) {
  die('ERROR:' . $e->getMessage());  
}
?>

一个简单的应用

现在您已经知道Google Contacts Data API的工作原理,可以尝试构建一个简单PHP应用程序,该应用程序允许输入和操作联系人。 该原型应用程序具有3个脚本(有关压缩文件,请参见下载 ):

  • contacts-index.php列出了联系人条目,并提供了添加和删除条目的链接。
  • contacts-save.php将显示一个表单以添加新条目,并处理提交。
  • contacts-delete.php删除指定的条目。

从第一个脚本开始,并使用一些附加链接更新清单1 ,如清单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
    // load Zend Gdata libraries
    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');
    
    // set credentials for ClientLogin authentication
    $user = "user@gmail.com";
    $pass = "guessme";
    
    try {
      // perform login and set protocol version to 3.0
      $client = Zend_Gdata_ClientLogin::getHttpClient(
        $user, $pass, 'cp');
      $gdata = new Zend_Gdata($client);
      $gdata->setMajorProtocolVersion(3);
      
      // perform query and get feed of all results
      $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);
      
      // display number of results
      ?>
      
      <h2><?php echo $feed->title; ?></h2>
      <div>
      <?php echo $feed->totalResults; ?> contact(s) found.
      </div>
            
      <?php
      // parse feed and extract contact information
      // into simpler objects
      $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    
    // display results
    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中可以看到,每个条目旁边现在都有一个附加的Delete链接。 该链接包括条目ID,该条目ID作为GET参数传递到链接目标。 目标脚本读取此ID并使用清单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
    // load Zend Gdata libraries
    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');
    
    // set credentials for ClientLogin authentication
    $user = "user@gmail.com";
    $pass = "guessme";
    
    if (empty($_GET['id'])) {
      die('ERROR: Missing ID');
    } 

    try {
      // perform login and set protocol version to 3.0
      $client = Zend_Gdata_ClientLogin::getHttpClient(
        $user, $pass, 'cp');
      // set GData delete headers
      $client->setHeaders('If-Match: *');
      $gdata = new Zend_Gdata($client);
      $gdata->setMajorProtocolVersion(3);
      
      // delete entry
      $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 { 

      // check for required input      
      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');
      } 
      
      // sanitize input and save to array
      $inputData['name'] = htmlentities($_POST['name']);
      $inputData['email'] = htmlentities($_POST['email']);
      $inputData['org'] = htmlentities($_POST['org']);
      
      // load Zend Gdata libraries
      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');
      
      // set credentials for ClientLogin authentication
      $user = "user@gmail.com";
      $pass = "guessme";
      
      try {
        // perform login and set protocol version to 3.0
        $client = Zend_Gdata_ClientLogin::getHttpClient(
          $user, $pass, 'cp');
        $gdata = new Zend_Gdata($client);
        $gdata->setMajorProtocolVersion(3);
        
        // create new entry
        $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);
        
        // add name element
        $name = $doc->createElement('gd:name');
        $entry->appendChild($name);
        $fullName = $doc->createElement('gd:fullName', $inputData['name']);
        $name->appendChild($fullName);
        
        // add email elements
        $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);          
        }
        
        // add org name element
        $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);
        
        // insert entry
        $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代码。 图5说明了此表单的外观。

图5.一个添加新联系人的Web表单
带有表单字段以添加新联系人的网页的屏幕截图

用户在此表单中输入联系人的姓名,电子邮件地址和组织并将其提交后,脚本的后半部分即会生效。 首先,初始化HTTP客户端并将其用于打开与Google Contacts Data API的身份验证连接。 接下来,验证输入到Web表单中的输入,并初始化一个新的DOMDocument对象以保存新条目的数据。

然后,PHP中的DOM方法动态地构造一个新的<entry>,而insertEntry()方法实际上将条目保存到Google服务器。 添加条目后,API将返回其唯一ID,该ID将显示给用户以指示操作成功。

图6说明了成功添加新条目后的输出。

图6.添加新联系人后的输出
添加新联系人后输出的屏幕截图

图6的屏幕截图中,Google的确认消息中掩盖了某些字段。 该消息的格式为: The ID of the new entry is http://www.google.com/m8/feeds/contacts/USER_ID/base/CONTACT_ID.

结论

在本文中,您学习了速成课程,内容涉及如何结合使用SimpleXML和Zend客户端库将Google Contacts Data API中的数据集成到PHP应用程序中。 本文中的示例向您介绍了Google Contacts feed格式; 向您展示了如何检索联系人列表; 添加,修改和删除联系人; 并为存储在用户Google帐户中的联系信息数据构建自定义界面。

如这些示例所示,对于希望围绕联系人管理构建富有创意的新应用程序的开发人员而言,Google Contacts Data API是一款功能强大且灵活的工具。 有时玩,看看你的想法!


翻译自: https://www.ibm.com/developerworks/opensource/library/x-phpgooglecontact/index.html

通讯录php

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值