内容


利用 PHP 搜索和集成 Google Buzz 流

借助一个 web 应用程序,用 PHP 处理和集成来自 Google Buzz 的活动流

Comments

简介

自从 2010 年 2 月发布以来,Google Buzz 确实已经产生了不小的轰动。通过允许用户共享多媒体内容(比如视频和照片),以及提供简单的状态更新,Buzz 很快成为了 Google 最流行的服务之一,与 Gmail 的紧密集成也无妨!

如果您是一位 web 可开发人员,会有更多的理由为 Google Buzz 感到兴奋。跟很多其他 Google 服务一样,Google Buzz 也带有一个开发人员 API,让您可以深入服务的内部,利用它创建自己的混搭应用程序(mashups)。由于此 API 使用 REST,所以您可以轻松地将之与大多数编程工具包(包括我最经常使用的 PHP)集成。

本文向您介绍 Google Buzz API,并借助一个 PHP 应用程序向您展示如何集成和使用 Google Buzz 内容。我们马上开始吧!

理解 Google Buzz 提要

在开始利用 Google Buzz 开发应用程序之前,您首先需要理解它是如何工作的。跟所有基于 REST 的服务一样,首先从一个针对指定资源的 HTTP 请求开始。这个 HTTP 请求包含一个带有一个或多个输入参数的查询;服务器用一个 Atom 或 JSON 提要响应该查询。请求中使用的 HTTP “动词” — GET 用于读,POST 和 PUT 用于写,DELETE 用于删除 — 指出所需操作的类型,服务器返回的 HTTP 状态代码指出操作是否成功。

要明白这是如何工作的,请在您喜欢的 web 浏览器中登录您的 Google 帐户并尝试请求 URL https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@public。记住用您的 Google ID 替换 URL 中的字符串 YOUR_ID;您可以从 Google Profile URL(显示在您的 Google Account Settings 页面中)获得 Google ID。对该请求(您可以在结果页面的源代码中查看)的响应将包含一系列您的最近 Google Buzz 帖子,可能类似于 清单 1

清单 1. 一个示例 Google Buzz 提要
<?xml version="1.0" encoding="UTF-8"?>
<feed gd:kind="buzz#activityFeed" 
  xmlns="http://www.w3.org/2005/Atom" 
  xmlns:activity="http://activitystrea.ms/spec/1.0/" 
  xmlns:buzz="http://schemas.google.com/buzz/2010" 
  xmlns:crosspost="http://purl.org/syndication/cross-posting" 
  xmlns:gd="http://schemas.google.com/g/2005" 
  xmlns:georss="http://www.georss.org/georss" 
  xmlns:media="http://search.yahoo.com/mrss/" 
  xmlns:poco="http://portablecontacts.net/ns/1.0" 
  xmlns:thr="http://purl.org/syndication/thread/1.0">
  <link href="http://pubsubhubbub.appspot.com/" rel="hub"/>
  <link 
   href="https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@public?alt=atom"
   rel="self" type="application/atom+xml"/>
  <title type="text">Google Buzz Public Feed</title>
  <updated>2010-06-24T18:16:47.108Z</updated>
  <id>tag:google.com,2010:buzz-feed:public:posted:YOUR_ID</id>
  <generator uri="http://www.google.com/buzz">Google Buzz</generator>
  <entry gd:kind="buzz#activity">
    <title>Watching it rain and planning tomorrow's shopping</title>
    <published>2010-06-18T14:13:51.000Z</published>
    <updated>2010-06-18T14:13:51.400Z</updated>
    <id>tag:google.com,2010:buzz:s12ard75xvreh35</id>
    <link href="http://www.google.com/buzz/YOUR_ID/fqFn7S27Va4" rel="alternate" 
     type="text/html"/>
    <link href="https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@self/
     tag:google.com,2010:buzz:s12ard75xvreh35?alt=atom" rel="self" 
     type="application/atom+xml"/>
    <link href="https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@self/
     tag:google.com,2010:buzz:s12ard75xvreh35/@comments?alt=atom" rel="replies" 
     thr:count="0" thr:updated="2010-06-18T14:13:51.400Z" 
     type="application/atom+xml"/>
    <author>
      <poco:id>YOUR_ID</poco:id>
      <poco:photoUrl/>
      <name>Vikram Vaswani (Melonfire)</name>
      <uri>http://www.google.com/profiles/YOUR_ID</uri>
      <link href="" rel="photo" type="image/jpeg"/>
      <activity:object-type>http://activitystrea.ms/schema/1.0/
       person</activity:object-type>
    </author>
    <content type="text/html">Watching it rain and planning 
     tomorrow&#39;s shopping</content>
    <activity:verb>http://activitystrea.ms/schema/1.0/post
     </activity:verb>
    <activity:object>
      <activity:object-type>http://activitystrea.ms/schema/1.0/note
       </activity:object-type>
      <content type="text/html">Watching it rain and planning 
       tomorrow&#39;s shopping</content>
      <buzz:original-content type="text"/>
      <link href="http://www.google.com/buzz/YOUR_ID/fqFn7S27Va4" 
       rel="alternate" type="text/html"/>
    </activity:object>
    <source>
      <activity:service>
        <title>Buzz</title>
      </activity:service>
    </source>
    <buzz:visibility>
      <buzz:aclentry type="group">
        <poco:id>tag:google.com,2010:buzz-group:@me:@public</poco:id>
        <uri>https://www.googleapis.com/buzz/v1/people/@me/
         @groups/@public?alt=atom</uri>
        <poco:name>Public</poco:name>
      </buzz:aclentry>
    </buzz:visibility>
    <link buzz:count="0" href="https://www.googleapis.com/buzz/v1/
     activities/YOUR_ID/@self/tag:google.com,2010:buzz:s12ard75xvreh35/
     @liked?alt=atom" rel="http://schemas.google.com/buzz/2010#liked" 
     type="application/poco+xml"/>
  </entry>
  <entry>
  ...
  </entry>
</feed>

Google Buzz API 利用一个包含所请求数据的 Atom 或 JSON 提要响应 REST 请求。Google Buzz 提供很多有趣的提要,比如说:

  • per-user activity 提要,其中包含某个特定用户发布的所有公共帖子
  • global activity 提要,其中包含 Google Buzz 上的所有公共帖子
  • per-activity comments 提要,其中包含一系列对某个活动的用户评论
  • per-user person 提要,其中包含某个特定用户关注和被关注的一系列用户

这些提要中有些是公共可访问和可搜索的;另外一些只对经过成功身份认证的提要所有者可用。大多数提要支持通过身份认证后的读和写操作;这表示通过身份认证后的用户可以编程方式向其 public activity 提要发布新内容,或者通过 Google Buzz API 在其他用户的公共提要上写评论。

提要本身是一个标准 Atom 提要,最外层的 <feed> 元素包含多个 <link> 元素,它们的内容是结果集的当前页面(也可以是下一页面和前一页面)的 URL。最外层的 <feed> 元素也包含一个或多个 <entry> 元素,分别代表一个 Google Buzz 帖子。每个项包含描述性元数据,包括帖子 ID、标题、作者、发布日期和 URL。每个 <entry> 也包含一个 <author> 元素和多个 <link>元素,前者提供帖子作者的 profile ID、profile URL、照片 URL 和姓名,后者提供到帖子评论提要或相似提要的 URL 链接。

有必要单独提一下 <activity:> 名称空间元素,它提供关于 Google Buzz 活动的特定信息。<activity:verb> 元素指定活动的类型,<activity:object> 元素则指定活动的内容。

在继续之前,注意 Google Buzz 内容在第三方应用程序中的使用受 Google Buzz Terms of Service 限制。您的应用程序也应该遵循 Google Buzz Developer Policies 和 Branding Guidelines。您有必要在开始开发之前仔细阅读这些文档,以确保遵循所有必要的规则。参见 参考资料 中到这三个指南的链接。

检索公共帖子

既然您已经知道如何通过公共 REST API 访问 Google Buzz 活动提要,现在就来看从一个 PHP 应用程序中做这同一件事。一种方法是使用 PHP 的内置 XML 处理扩展(SimpleXML、DOM 或 XMLReader)解析 Google Buzz 返回的 Atom 提要,并从中摘取相关的信息片段。但是这会非常繁琐,尤其是处理大型提要或大量名称空间信息时。

还存在另外两种更方便的方法:

  • Zend Framework 中的 Zend_Rest_Client 组件是专为试图集成 PHP 应用程序和基于 REST 的 web 服务的开发人员设计的。您使用此客户端来执行对 REST 服务端点的 GET、POST、PUT 和 DELETE 响应。REST 响应被作为 Zend_Rest_Client_Response 对象的实例返回,使得访问单个响应属性很容易。
  • Google Buzz PHP Client Library 是一个专门设计来用于 Google Buzz 提要的开源客户端库。此库也将 Google Buzz 提要作为原生 PHP 对象返回,从而简化了数据访问。

要使用 Google Buzz PHP Client Library,您也需要将您的 web 应用程序注册到 Google 并获得进行 OAuth 身份认证所必需的 OAuth 消费方机密(consumer secret)。您会在 参考资料 中找到这两个库的下载链接和用法说明。安装这些库时,请记住更新您的 PHP 'include_path',以反映它们的位置。

这两种方法哪个更好?目前来说,Google Buzz PHP Client Library 更胜一筹,因为它也包含 OAuth 身份认证支持。该支持大大减少了发送经过身份认证的请求到 Google Buzz 服务所涉及到的工作。专家用户还可以组合使用 Zend_Rest_Client 库和 Zend_Oauth 组件来获得相同的结果,但是过程稍微复杂一些。因此,本文中的示例将使用 Google Buzz PHP Client Library,尽管前几个示例也将演示将 Zend_Rest_Client 库用于未经身份认证的请求。

清单 2 演示如何使用 Google Buzz PHP Client Library 来检索和解析用户的公共活动提要(清单 1 中的相同提要):

清单 2. 利用 Buzz PHP 客户端列出公共帖子
<?php
// include PHP client library
require_once 'buzz.php';

try {
  // set up file store
  $storage = new buzzFileStorage('/tmp/cache');
  
  // get user ID
  $uid = 1;

  // perform authentication with Google 
  $auth = buzzOAuth::performOAuthLogin($storage, $uid);

  // initialize Buzz object  
  $buzz = new buzz($storage, $auth);
      
  // fetch authenticated user's public feed
  $result = $buzz->getPosts('@public', '@me');

  // iterate through feed data
  echo '<h1>' . $result->title . '</h1>';
  echo count($result->posts) . ' post(s) found. <br/>';
  echo '<ol>';
  foreach ($result->posts as $post) {
    echo '<li>';
    echo isset($post->links['alternate'][0]->href) ? 
     '<a href="' . $post->links['alternate'][0]->href . 
     '">' . $post->title . '</a>' : $post->title;
    echo ' (' . date("d M Y h:i", strtotime($post->published)) . ')';  
    echo '</li>';
  }
  echo '</ol>';
} catch (Exception $e) {
  echo 'ERROR:' . $e->getMessage();  
}
?>

清单 2 从包含源文件开始,然后创建一个新的 buzz 对象。这个 buzz 对象充当与 Google Buzz API 进行通信的中心点,提供多种方法访问 Google Buzz 数据。要初始化该对象,向构造函数传递两个参数:

  • 一个适当配置的 buzzStorage 对象,它指定局部高速缓存将如何发生。Google Buzz PHP Client Library 支持 Alternative PHP Cache (APC)、memcached 和基于文件的高速缓存,三者分别由 buzzApcStoragebuzzMemcacheStoragebuzzFileStorage 类表示。
  • 一个适当配置的 buzzOAuth 对象。该对象由静态 buzzOAuth::performOAuthLogin() 方法产生,此方法接受两个参数:一个 buzzStorage 对象和一个局部用户标识符。buzzOAuth::performOAuthLogin() 然后负责执行到 Google 服务器的 OAuth 身份认证,会向用户显示适当的提示以接受或拒绝对用户 Google Buzz 数据的应用程序访问,以及执行必要的重定向。

一旦创建了初始的 buzz 对象,您就可以使用对象的 getPosts() 方法访问用户的活动提要。该方法接受 5 个参数:提要类型、用户 ID,以及包含在提要结果中的评论数量、likes 和帖子。该方法的返回值是一系列嵌套的 PHP 对象,分别代表底层 Atom 结果提要中的一个项。现在迭代通过这个对象集合并使用标准的对象->属性表示法摘取相关信息用于显示已变得相当容易。图 1 演示了结果看起来的样子。

图 1. 一个公共帖子列表
五个公共帖子的列表的屏幕截图,包括到这些帖子的链接
五个公共帖子的列表的屏幕截图,包括到这些帖子的链接

下面简要介绍一下提要类型。Google Buzz API 提供三种提要类型:

  1. 用户的公共 提要,它包含用户的公共帖子,被引用为 @public。该提要通常位于 https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@public
  2. 用户的消费 提要,它包含来自被跟随用户的帖子,被引用为 @consumption。该提要通常位于 https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@consumption
  3. 用户的个人 提要,它包含用户的公共和私人帖子,被引用为 @personal。该提要通常位于 https://www.googleapis.com/buzz/v1/activities/YOUR_ID/@personal

消费提要和个人提要需要身份认证,而公共提要则不需要。特殊的用户 ID 字符串 @me 也可以被用作一个方便的简称,代表“当前经过身份认证的用户”,取代数值 Google ID。

清单 3 使用 Zend_Rest_Client 库产生一个等价于 清单 2 的结果:

清单 3. 利用 Zend REST 客户端列出公共帖子
<?php
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

try {
  // get feed of user public activities
  $client = new Zend_Rest_Client('https://www.googleapis.com/buzz/v1/
   activities/YOUR_ID_HERE/@public');
  $result = $client->get();
  
  // iterate through returned feed  
  echo '<h1>' . $result->title . '</h1>';
  echo count($result->entry) . ' post(s) found. <br/>';
  echo '<ol>';
  foreach ($result->entry as $entry) {
    echo '<li>';
    echo isset($entry->link[0][@href]) ? '<a href="' . 
     $entry->link[0][@href] . '">' . $entry->content . 
     '</a>' : $entry->content;
    echo ' (' . date("d M Y h:i", strtotime($entry->published)) . ')';  
    echo '</li>';
  }
  echo "</ol>";
  
} catch (Exception $e) {
  echo 'ERROR:' . $e->getMessage();
}   
?>

清单 3 首先加载 Zend 类库,然后初始化 Zend_Rest_Client 类的一个实例。使用该客户端来为用户的公共提要初始化一个未经身份认证的 GET 请求,就像您前面在 清单 1 中所做的一样。注意本例中的提要 URL 必须包含用户的 Google Profile ID。返回的 Atom 提要然后被解析并转换成 Zend_Rest_Client_Response 对象。跟前面一样,现在迭代通过此对象集合并从中摘取出特定帖子的详细信息变得相当容易。

搜索公共帖子

Google Buzz API 不包含搜索特性那是不可思议的;毕竟,这是 Google 的 API。因此,该 API 提供一个公共搜索提要,可以由所有用户用来搜索所有公共的帖子,并返回那些符合指定搜索条件的帖子。此公共搜索提要可在 https://www.googleapis.com/buzz/v1/activities/search 处访问到。

如果您使用的是 Google Buzz PHP Client Library,那么可以简单地调用 search() 方法并向它传递您的查询条件。清单 4 演示了:

清单 4. 利用 Buzz PHP 客户端搜索帖子
<!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>Searching public activity feeds</title>
    <style>
    body {
      font-family: Verdana;      
    }
    li {
      border-bottom: solid black 1px;      
      margin: 10px; 
      padding: 2px; 
      width: auto;
      padding-bottom: 20px;
    }
    </style>    
  </head>
  <body>  
    <form method="post" 
     action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for: <input type="text" name="q" />
    <input type="submit" name="submit" value="Search">
    </form>    
    <?php

    if (isset($_POST['submit'])) {
      // include PHP client library
      require_once 'buzz.php';

      try {
        // set up file store
        $storage = new buzzFileStorage('/tmp/cache');

        // get user ID
        $uid = 1;

        // perform authentication with Google 
        $auth = buzzOAuth::performOAuthLogin($storage, $uid);

        // initialize Buzz object  
        $buzz = new buzz($storage, $auth);

        // fetch authenticated user's public feed
        $result = $buzz->search($_POST['q']);

        // iterate through feed data
        echo '<h1>' . $result->title . '</h1>';
        echo count($result->posts) . ' post(s) found. <br/>';
        echo '<ol>';
        foreach ($result->posts as $post) {
          echo '<li>';
          echo isset($post->links['alternate'][0]->href) ? 
           '<a href="' . $post->links['alternate'][0]->href . 
           '">' . $post->title . '</a><br/>' : 
           $post->title . '<br/>';
          echo $post->person->name . ' (' . 
           date("d M Y h:i", strtotime($post->published)) . ')';  
          echo '</li>';
        }
        echo '</ol>';
      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();  
      }
    }
    ?>
  </body>
</html>

清单 4 首先显示一个 web 表单,以便用户输入一个或多个搜索条件。一旦该表单被提交,脚本就会创建一个新的 buzz 对象,并将搜索条件传递给对象的 search() 方法。此方法生成必要的针对 Google Buzz API 的 REST 请求,并将结果提要转换成一个 buzzPost 对象集合。现在所有剩下要做的就是迭代通过集合,打印出每个帖子的内容、作者和发布日期。

图 2 演示了一次搜索 chocolate 的结果。

图 2. Google Buzz 搜索的结果
Google Buzz 搜索单词 'chocolate' 的结果的屏幕截图,显示了 100 个帖子中的 3 个
Google Buzz 搜索单词 'chocolate' 的结果的屏幕截图,显示了 100 个帖子中的 3 个

由于搜索提要是公共的,所以您也可以使用任何未经身份认证的 HTTP 客户端查询它。清单 5 演示了通过使用 Zend_Rest_Client 库来直接请求搜索提要 URL 和处理响应:

清单 5. 利用 Zend REST 客户端搜索帖子
<!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>Searching public activity feeds</title>
    <style>
    body {
      font-family: Verdana;      
    }
    li {
      border-bottom: solid black 1px;      
      margin: 10px; 
      padding: 2px; 
      width: auto;
      padding-bottom: 20px;
    }
    </style>    
  </head>
  <body>  
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for: <input type="text" name="q" />
    <input type="submit" name="submit" value="Search">
    </form>    
    <?php

    if (isset($_POST['submit'])) {
      // load Zend classes
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Rest_Client');

      try {
        if (empty($_POST['q'])) {
          throw new Exception('No search term provided');  
        }

        // search all feeds
        $url = 'https://www.googleapis.com/buzz/v1/activities/search?q=' . 
         urlencode($_POST['q']);
        $client = new Zend_Rest_Client($url);
        $result = $client->get();

        // iterate through returned feed  
        // display results
        echo '<h1>' . $result->title . '</h1>';
        echo count($result->entry) . ' post(s) found. <br/>';
        echo '<ol>';
        foreach ($result->entry as $entry) {
          echo '<li>';
          echo '<a href="' . $entry->link[0][@href] . '">' . 
           $entry->content . '</a><br/>';  
          echo $entry->author->name;
          echo ' (' . date("d M Y h:i", strtotime($entry->published)) . ')';  
          echo '</li>';
        }
        echo "</ol>";
      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();
      }              
    }
    ?>
  </body>
</html>

清单 5 初始化一个新的 REST 客户端,并使用它向公共搜索提要发送一个未经身份认证的 GET 请求。用户提供的搜索参数是 URL 编码的,并通过特殊的 q 参数附加到此请求。您使用 foreach() 循环来迭代通过得到的对象集合,如 清单 3 中所示,以产生等价于 清单 4 中的输出。

跟其他 Google 提要一样,Google Buzz API 允许开发人员通过向 REST 查询添加以下参数来定制输出:

  • alt 参数,它指定提要格式('atom' 或 'json')
  • max-results 参数,它指定检索到的最大项数
  • max-comments 参数,它指定每一项检索到的最大评论数
  • latlon 参数,它们指定搜索结果的地理筛选条件

也可以向请求 URL 附加高级搜索查询操作符。参考 Google Buzz API Developers Guide(参见 参考资料 中的链接),获得操作符的完整列表,还有示例。

添加、编辑和删除帖子

已经学习了帖子的列出和搜索,那么如何添加、编辑和删除帖子呢?

作为一个遵循 REST 的 API,Google Buzz API 支持使用常规 HTTP 动词来指出所需操作的类型。因此,要添加新帖子,只需要向提要 URL 发送一个未经身份认证的 POST 请求即可,将帖子内容附加到请求主体。类似地,要编辑或删除帖子,则需要向提要 URL 发送一个包含帖子 ID 的未经身份认证的 PUT 或 DELETE 请求。

为了简化开发人员的工作,Google Buzz PHP Client Library 将以上任务封装在两个方法中:updatePost()deletePost()。为了举例说明,请考虑 清单 6,它演示了如何利用 PHP 添加新 Google Buzz 帖子:

清单 6. 添加帖子
<?php
// include PHP client library
require_once 'buzz.php';

try {
  // set up file store
  $storage = new buzzFileStorage('/tmp/cache');
  
  // get user ID
  $uid = 1;

  // perform authentication with Google 
  $auth = buzzOAuth::performOAuthLogin($storage, $uid);

  // initialize Buzz object  
  $buzz = new buzz($storage, $auth);

  // add a new post
  $object = new buzzObject('Adding this post through the Buzz API...woohoo!');
  $post = buzzPost::createPost($object);
  $result = $buzz->updatePost($post);
  echo 'Added new post with ID: ' . $result->id;  
} catch (Exception $e) {
  echo 'ERROR:' . $e->getMessage();  
}
?>

您的第一件事是创建一个新 buzz 实例。然后,创建一个新 buzzObject 实例,并用将发布的内容初始化它。然后通过 buzzPost::createPost() 方法将这个 buzzObject 转换成一个 Google Buzz 项,并使用 updatePost() 方法将整个请求包 POST 到 Google Buzz 服务器。一旦新帖子被创建,服务器就会发送回一个 201 (Created) 状态码和一个完整的 <entry> 段(代表新添加的帖子)。

图 3 展示了 清单 6 的输出:

图 3. 添加新 Google Buzz 帖子的结果
添加新 Google Buzz 帖子的结果的屏幕截图:添加了一个 ID 为 tag:google.com,2010:buzz:z13 的新帖子
添加新 Google Buzz 帖子的结果的屏幕截图:添加了一个 ID 为 tag:google.com,2010:buzz:z13 的新帖子

编辑帖子稍微有点不同:您必须首先创建一个新帖子,然后将它的 ID 设置为您希望替换的帖子的 ID。清单 7 演示了:

清单 7. 修改帖子
<?php
// include PHP client library
require_once 'buzz.php';

try {
  // set up file store
  $storage = new buzzFileStorage('/tmp/cache');

  // get user ID
  $uid = 1;

  // perform authentication with Google 
  $auth = buzzOAuth::performOAuthLogin($storage, $uid);

  // initialize Buzz object  
  $buzz = new buzz($storage, $auth);

  // edit a post
  $object = new buzzObject('Updating this post through the Buzz API...yeehaw!');
  $post = buzzPost::createPost($object);
  $post->id = 'tag:google.com,2010:buzz:z133';    
  $result = $buzz->updatePost($post);
  echo 'Updated post with ID: ' . $result->id;  
} catch (Exception $e) {
  echo 'ERROR:' . $e->getMessage();  
}
?>

清单 7 中,代码利用正确的内容初始化一个新的 buzzPost 对象,并将它的 ID 设置为要编辑的帖子的 ID。updatePost() 方法然后发送一个带有已修订项的 PUT 请求到 Google Buzz 服务器。如果成功,服务器将用一个 201 (OK) 状态码和修订后的 <entry> 进行响应。图 4 展示了可能的输出:

图 4. 编辑 Google Buzz 帖子的结果
编辑 Google Buzz 帖子的结果的屏幕截图:更新后的帖子的 ID 为 tag:google.com,2010:buzz:z133
编辑 Google Buzz 帖子的结果的屏幕截图:更新后的帖子的 ID 为 tag:google.com,2010:buzz:z133

删除帖子相当简单:向 deletePost() 方法提供帖子 ID,Google Buzz PHP Client Library 将构造一个 DELETE 请求,并传输到 REST API。清单 8 演示了这个过程:

清单 8. 删除帖子
<?php
// include PHP client library
require_once 'buzz.php';

try {
  // set up file store
  $storage = new buzzFileStorage('/tmp/cache');

  // get user ID
  $uid = 1;

  // perform authentication with Google 
  $auth = buzzOAuth::performOAuthLogin($storage, $uid);

  // initialize Buzz object  
  $buzz = new buzz($storage, $auth);

  // delete a post
  $id = 'tag:google.com,2010:buzz:z13';
  $buzz->deletePost($id);
  echo 'Deleted post with ID: ' . $id;  
} catch (Exception $e) {
  echo 'ERROR:' . $e->getMessage();  
}
?>

图 5 显示了结果:

图 5. 删除 Google Buzz 帖子的结果
删除 Google Buzz 帖子的结果的屏幕截图:被删除帖子的 ID 为 tag:google.com,2010:buzz:z13
删除 Google Buzz 帖子的结果的屏幕截图:被删除帖子的 ID 为 tag:google.com,2010:buzz:z13

搜索用户

除了允许搜索关键词之外,Google Buzz API 还允许您按姓名搜索人。实现的方法是,发送一个 HTTP GET 请求到 URL https://www.googleapis.com/buzz/v1/people/search,并附加必需的搜索条件。该请求的响应是一个 Atom 或 JSON 提要,其中包含一系列匹配的用户,以及他们的姓名和 Google ID。

清单 9 演示了如何使用 Google Buzz PHP Client Library 做到这一点:

清单 9. 利用 Buzz PHP 客户端搜索用户
<!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>Searching for people</title>
    <style>
    table {
      border-collapse: yes;      
    }
    tr {
      border-bottom: solid black 1px;      
    }
    td {
      vertical-align: top;  
      border: solid black 1px;      
    }
    li {
      margin: 10px; 
      padding: 2px; 
      width: auto;
      padding-bottom: 20px;
    }
    </style>    
  </head>
  <body>  
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for people: <input type="text" name="q" />
    <input type="submit" name="submit" value="Search">
    </form>    
    <?php
    if (isset($_POST['submit'])) {
      // include PHP client library
      require_once 'buzz.php';

      try {
        // set up file store
        $storage = new buzzFileStorage('/tmp/cache');

        // get user ID
        $uid = 1;

        // perform authentication with Google 
        $auth = buzzOAuth::performOAuthLogin($storage, $uid);

        // initialize Buzz object  
        $buzz = new buzz($storage, $auth);

        // fetch authenticated user's public feed
        $result = $buzz->searchPeople($_POST['q']);

        // iterate through feed data
        echo '<h1>Search Results</h1>';
        echo '<table>';        
        foreach ($result as $person) {
          echo '<tr>';
          // display user full name and photo
          echo '<td><img src="' . $person->thumbnailUrl . 
           '" /><br/>';  
          echo '<strong>' . $person->name . 
           '</strong></td><td>';

          // fetch user's public feed
          $result = $buzz->getPosts('@public', 
           $person->id, false, false, 3);

          // iterate through feed data 
          echo 'Recent updates: <br/>';
          echo '<ol>';
          foreach ($result->posts as $post) {
            echo '<li>';
            $url = isset($post->links->self[0]->href) ? 
             $post->links->self[0]->href : '#';
            echo '<a href="' . $url . '">' . $post->title . '</a>';  
            echo ' (' . date("d M Y h:i", strtotime($post->published)) . ')';  
            echo '</li>';
          }
          echo '</ol></td>';    
          echo '</tr>';    
        }        
        echo '</table>';
      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();  
      }
    }
    ?>
  </body>
</html>

清单 9 要求用户在搜索表单中输入一个人的姓名,然后使用 searchPeople() 方法查询 Google Buzz API,以找到匹配的人。该方法的返回值是一个 buzzPerson 对象集合,每个对象都包含关于用户的信息:名和姓、Google ID、Google Profile URL、照片 URL 以及其他个人信息。清单 9 摘取该信息,然后使用 Google ID 及 getPosts() 方法检索此用户的最近三个帖子。所有这些信息都被格式化为可读的 web 页面,如 图 6 所示。

图 6. Google Buzz 人员搜索的结果
Google Buzz 人员搜索的结果的屏幕截图,带有三个样例项
Google Buzz 人员搜索的结果的屏幕截图,带有三个样例项

清单 10 提供 清单 9 的一个替代方法,即使用 Zend_Rest_Client 库来得到相同结果:

清单 10. 利用 Zend REST 客户端搜索用户
<!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>Searching for people</title>
    <style>
    table {
      border-collapse: yes;      
    }
    tr {
      border-bottom: solid black 1px;
    }
    td {
      vertical-align: top;  
      border: solid black 1px; 
    }
    li {
      margin: 10px; 
      padding: 2px; 
      width: auto;
      padding-bottom: 20px;
    }
    </style> 
  </head>
  <body>  
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for people: <input type="text" name="q" />
    <input type="submit" name="submit" value="Search">
    </form>
    <?php
    if (isset($_POST['submit'])) {
      // load Zend classes
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Rest_Client');

      try {
        if (empty($_POST['q'])) {
          throw new Exception('No search term provided');  
        }

        // search people feed
        $client = new Zend_Rest_Client('https://www.googleapis.com/buzz/v1/
         people/search?q=' . urlencode($_POST['q']));
        $result = $client->get();

        // iterate through returned feed  
        // for each result, display user name and photo
        echo '<h1>Search Results</h1>';
        echo '<table>';
        foreach ($result->entry as $entry) {
          echo '<tr>';
          echo '<td><img src="' . $entry->thumbnailUrl . 
           '" /><br/>';  
          echo $entry->displayName . '</td><td>';
          // get feed of user's three most recent public posts
          $client2 = new Zend_Rest_Client('https://www.googleapis.com/buzz/
           v1/activities/' . $entry->id . '/@public?max-results=3');
          $result2 = $client2->get();
          echo 'Recent updates: <br/>';
          echo '<ol>';
          foreach ($result2->entry as $entry2) {
            echo '<li>';
            echo '<a href="' . $entry2->link[0][@href] . '">' . 
             $entry2->content . '</a>';  
            echo ' (' . date("d M Y h:i", strtotime($entry2->published)) . ')';  
            echo '</li>';
          }
          echo "</ol></td>";
          echo '</tr>';
        }
        echo '</table>';
      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();
      }
    }
    ?>
  </body>
</html>

清单 10 使用 Zend_Rest_Client 库来直接访问人员搜索服务的 REST 端点,返回 Atom 提要的一个对象表示。该对象集合可在需要时用来摘取相关信息。注意,在本例中,查询条件必须是手动 URL 编码的。

管理追随者

Google Buzz 允许用户相互“追随”。追随一个用户会自动让该用户的帖子成为追随者消费提要的一部分。Google Buzz API 使得该信息分别通过 followerfollowing 提要而在 https://www.googleapis.com/buzz/v1/people/YOUR_ID/@groups/@followers 和 https://www.googleapis.com/buzz/v1/people/YOUR_ID/@groups/@following URL 处可用。

要使用 PHP 客户端库获得该信息,可使用 followers()following() 方法,它们分别返回给出用户 follower(关注您的人) 和 following(您关注的人) 的 buzzPerson 对象集合。清单 11 有一个示例:

清单 11. 列出 follower 和 following
<?php
// include PHP client library
require_once 'buzz.php';

try {
  // set up file store
  $storage = new buzzFileStorage('/tmp/cache');
  
  // get user ID
  $uid = 1;

  // perform authentication with Google 
  $auth = buzzOAuth::performOAuthLogin($storage, $uid);

  // initialize Buzz object  
  $buzz = new buzz($storage, $auth);

  // get followers
  $followers = $buzz->followers('@me');

  echo '<h1>Currently being followed by:</h1>';
  foreach ($followers as $person) {
    displayUserBlock($person);
  }

  // get following
  $following = $buzz->following('@me');
  echo '<h1>Currently following:</h1>';
  foreach ($following as $person) {
    displayUserBlock($person);
  }

} catch (Exception $e) {
  echo 'ERROR:' . $e->getMessage();
}

// render user block
function displayUserBlock($person) {
    // get object from global scope
    global $buzz;

    // display user full name
    echo '<strong>' . $person->name . '</strong><br/>';

    // fetch user's public feed
    $result = $buzz->getPosts('@public', $person->id, false, false, 3);

    // iterate through feed data
    echo '<ol>';
    foreach ($result->posts as $post) {
      echo '<li>';
      $url = isset($post->links->self[0]->href) ? 
       $post->links->self[0]->href : '#';
      echo '<a href="' . $url . '">' . $post->title . 
       '</a>';  
      echo ' (' . date("d M Y h:i", strtotime($post->published)) . ')';
      echo '</li>';
    }
    echo '</ol>';
}
?>

清单 11 首先使用 followers() 方法检索一系列经过身份认证的用户的 follower。该方法的返回值是一个 buzzPerson 对象集合,每个对象被传递给用户定义的 displayUserBlock() 方法。该方法检索每个 follower 的姓名和 ID,然后使用此 ID 发出第二个请求,此次通过 getPosts() 方法来检索 follower 的最近三个帖子。然后信息被格式化,以进行显示。

此后,使用 following() 方法检索一系列当前由经过身份认证的用户追随的用户。该方法返回的集合以类似的方式处理。

利用 Google Buzz API 也可以编程方式跟随或解除跟随特定的用户。这些 API 方法对应着 buzz 对象的 follow()unfollow() 方法,它们分别接受一个用户 ID 并向经过身份认证的用户的追随队列添加或删除该用户。

示例应用程序

既然您已经逐项了解 Google Buzz API 是如何工作的,现在我们组合成一个简单的 web 应用程序,演示如何交互地使用它。清单 12 更新 清单 2,即创建一个 Add 表单并向每个帖子附加 Delete 链接。添加的这些代码允许经过身份认证的用户查看他们的公共提要,交互地添加新帖子,或者删除现有帖子 — 所有这些操作都无需使用 Google Buzz 界面。

清单 12. 列出用户帖子
<!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>
    <style>
    body {
      font-family: Verdana;
    }
    li {
      margin: 10px; 
      padding: 2px; 
      width: auto;
      padding-bottom: 20px;
    }
    </style> 
  </head>
  <body>

  <h1>Add New Post</h1>
  <form method="post" action="add.php">
  Message: <br/>
  <textarea name="buzz" cols="60" rows="5"></textarea><br/>
  <input type="submit" name="submit" value="Post!" />
  </form>

  <h1>Recent Posts</h1>
  <?php
  // include PHP client library
  require_once 'buzz.php';

  try {
    // set up file store
    $storage = new buzzFileStorage('/tmp/cache');

    // get user ID
    $uid = 1;

    // perform authentication with Google 
    $auth = buzzOAuth::performOAuthLogin($storage, $uid);

    // initialize Buzz object  
    $buzz = new buzz($storage, $auth);

    // fetch authenticated user's public feed
    $result = $buzz->getPosts('@public', '@me');

    // iterate through feed data
    echo count($result->posts) . ' post(s) found. <br/>';
    echo '<ol>';
    foreach ($result->posts as $post) {
      echo '<li>';
      echo isset($post->links['alternate'][0]->href) ? 
       '<a href="' . $post->links['alternate'][0]->href . 
       '">' . $post->title . '</a>' : $post->title;
      echo ' (' . date("d M Y h:i", strtotime($post->published)) . ') ';
      echo '<a href="delete.php?id=' . $post->id . '">[Delete this post]</a>';
      echo '</li>';
    }
    echo '</ol>';
  } catch (Exception $e) {
    echo 'ERROR:' . $e->getMessage();
  }
  ?>

  </body>
</html>

清单 12 分为两部分:

  • 第一部分初始化一个 buzz 对象并使用它的 getPosts() 方法检索用户的公共提要。每个帖子都带有一个链接,从而允许用户通过 delete.php 脚本删除帖子。帖子 ID 被作为一个标准 GET 参数传递给 delete.php 脚本。
  • 第二部分包含一个 HTML 表单,表单为用户输入新帖子提供一个输入字段。经表单提交的数据通过 POST 传输到 add.php 脚本。

清单 13 包含 add.php 脚本,它通过 POST 接收输入数据,并将之转换成 buzzPost 对象。该对象然后被作为一个 POST 请求、通过前面讨论过的 updatePost() 方法传输到 Google Buzz 服务。清单 13 展示了此代码:

清单 13. 添加新帖子
<!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>
  </head>
  <body>
  <?php
  if (!isset($_POST['buzz'])) {
    die('ERROR: Please enter some Buzz content!');
  }

  // include PHP client library
  require_once 'buzz.php';

  try {
    // set up file store
    $storage = new buzzFileStorage('/tmp/cache');

    // get user ID
    $uid = 1;

    // perform authentication with Google 
    $auth = buzzOAuth::performOAuthLogin($storage, $uid);

    // initialize Buzz object  
    $buzz = new buzz($storage, $auth);

    // add a new post
    $object = new buzzObject($_POST['buzz']);
    $post = buzzPost::createPost($object);
    $result = $buzz->updatePost($post);
    echo 'Added new post with ID: ' . $result->id;  
  } catch (Exception $e) {
    echo 'ERROR:' . $e->getMessage();  
  }
  ?>

  </body>
</html>

清单 14 包含 delete.php 脚本,它接收将被删除的帖子的 ID,并将此 ID 传递给 deletePost() 方法。该方法构造一个 DELETE 请求并传递给 Google Buzz API 执行。下面是此代码:

清单 14. 删除帖子
<!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>
  </head>
  <body>
<?php
  if (!isset($_GET['id'])) {
    die('ERROR: Please provide a valid Buzz ID for deletion');
  }

  // include PHP client library
  require_once 'buzz.php';

  try {
    // set up file store
    $storage = new buzzFileStorage('/tmp/cache');

    // get user ID
    $uid = 1;

    // perform authentication with Google 
    $auth = buzzOAuth::performOAuthLogin($storage, $uid);

    // initialize Buzz object  
    $buzz = new buzz($storage, $auth);

    // delete a post
    $buzz->deletePost($_GET['id']);
    echo 'Deleted post with ID: ' . $id;  
  } catch (Exception $e) {
    echo 'ERROR:' . $e->getMessage();  
  }
  ?>
  </body>
</html>

图 7 显示了清单 12 的输出:

图 7. 一个用于 Google Buzz 交互的 web 表单
用于 Google Buzz 交互的 Message web 表单的屏幕截图;也展示了 6 个最近帖子中的 3 个
用于 Google Buzz 交互的 Message web 表单的屏幕截图;也展示了 6 个最近帖子中的 3 个

结束语

正如这些示例所演示的,利用 Google Buzz API 和 PHP Client Library 可以将 Buzz 帖子和活动流直接集成到 PHP 应用程序中。本文中的示例只涉及到冰山一角。您可以利用 Google Buzz 做很多事情,包括:

  • 创建私有活动
  • 屏蔽(Mute)、解除屏蔽(unmute)和喜欢帖子
  • 创建和编辑评论
  • 创建高级搜索查询

在撰写本文时,Google Buzz API 还在开发之中,所以您可以期待未来有更多的功能!

总之,Google Buzz API 为开发人员将公共 Buzz 内容集成到任何 web 应用程序中提供了一种完善的、格式独立的机制。它对于混搭应用程序或者构建您自己的定制 Google Buzz 界面非常有用。有时间自己去体验一下,看看您能利用它做些什么。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=XML, Open source
ArticleID=587294
ArticleTitle=利用 PHP 搜索和集成 Google Buzz 流
publish-date=11152010