利用 PHP 应用程序搜索并集成 Google+ 活动流

利用 Google+ API 和 PHP 在 Google+ 上检索帖子并查找用户

Google+ 是 Google 提供的新社交网络服务,允许用户发布状态信息和新闻。Web 应用程序开发人员可以通过 Google+ API 访问并搜索这些信息。本文将介绍 Google+ API 的基础知识。本文会提供一些示例,展示如何使用 Google+ API 和 PHP 来创建动态 Web 应用程序。

Vikram Vaswani, 创始人, Melonfire

Vikram Vaswani 的照片Vikram Vaswani 是 Melonfire 的创始人和 CEO,该公司是一家专门研究开源工具和技术的咨询服务公司。他还著有 PHP Programming SolutionsHow to do Everything with PHP and MySQL 等著作。



2012 年 8 月 27 日

简介

Google+ 是社交网络行业的新产品,是 Google 构建社交网络的最新尝试,可让用户轻松地与好友共享新闻和文件,并与他们进行互动。它似乎成功抓住了公众的想象力。据报道,截止 2011 年 12 月,每天都有 625,000 个新用户注册 Google+,用户总数已达到 6200 万(参阅 参考资料)。

常用缩写词

  • API:应用程序编程接口
  • HTTP:超文本传输协议
  • JSON:JavaScript 对象符号
  • PHP:超文本预处理程序

Web 开发人员有理由对 Google+ 感到兴奋。与其他许多 Google 服务一样,Google+ 随附提供了一个开发人员 API,允许您通过自己的自定义应用程序访问用户生成的内容。由于 API 以 JSON 形式提供其输出,因此它可以轻松与大多数编程工具包进行集成。

本文将介绍 Google+ Data API,了解如何使用它从 Google+ 提取内容,以及如何将它集成到 PHP 应用程序中。(这非常有趣,因此要预先警告您可能会沉溺于它。)


API 的基础知识

在使用 Google+ 开始开发应用程序之前,您需要了解它的工作原理。API 通过 HTTP 工作,并希望获得一个到指定端点的 HTTP 请求。收到此请求后,API 服务器会使用一个包含请求数据的 JSON 提要来响应查询。然后,可以使用服务器端编程语言(比如 PHP 或 Perl)或客户端工具包(比如 jQuery 或 mooTools)解析这些数据,并从中提取内容,以便将它集成到 Web 页面中。

首先您需要做几件事:

  1. 设置 Google+ 帐户。
    1. 登录 Google Account 并使用主菜单中的 "+You" 链接注册一个 Google+ 帐户。
    2. 转到 Google Account Settings 页面,检索您个性化的 Google Profile URL,该 URL 包含您的 Google ID,如 图 1 所示。
    3. 认真地记录此 ID;本文中的一些示例需要使用它。
    图 1. 带有 Google ID 的 Google Profile URL
    带有 Google ID 的 Google Profile URL
  2. 激活您 Google+ 帐户的 API 访问。
    1. 浏览到 Google APIs Console(参阅 参考资料 获得此控制台的链接),创建一个新项目。
    2. 为您的新项目激活 Google+ API。
    3. 您将会收到一个自动生成的 API 密钥,您可以使用它来访问 API。该密钥位于 Google APIs Console 的 API Access 选项卡下,如 图 2 所示。
    4. 认真地记录您的 API 密钥。
    图 2. 具有 API 访问密钥的 Google API Console
    具有 API 访问密钥的 Google API Console

您还可以使用 OAuth 访问 Google+ API。(OAuth 的讨论不在本文的讨论范围之内。)

获得了 Google+ ID 和 API 密钥后,在您的浏览器中尝试请求 API 端点 https://www.googleapis.com/plus/v1/people/ID/activities/public?key=API-KEY 。记住使用您刚获得的值替换请求中的 ID 和 API-KEY 占位符。您可以在生成页面的源代码中查看请求的响应,请求响应将包含一个最新的 Google+ 帖子列表。它类似于 清单 1。惟一标识符已经变得有些模糊。

清单 1. JSON 格式的 Google+ 活动提要示例
{
 "kind": "plus#activityFeed",
 "etag": "ab49djslas22",
 "nextPageToken": "eJxtbiSnOTUova1kyV5Z7y",
 "selfLink": "https://www.googleapis.com/plus/v1/people/ID/activities/public?",
 "nextLink": "https://www.googleapis.com/plus/v1/people/ID/activities/
    public?maxResults=20&pageToken=",
 "title": "Plus Public Activity Feed for John Doe",
 "updated": "2012-01-17T06:05:03.277Z",
 "id": "tag:google.com,2010:/plus/people/ID/activities/public",
 "items": [
  {
   "kind": "plus#activity",
   "etag": "abc",
   "title": "Sleepy at work",
   "published": "2012-01-17T06:05:03.000Z",
   "updated": "2012-01-17T06:05:03.277Z",
   "id": "zab",
   "url": "https://plus.google.com/ID/posts/XgGBBbn",
   "actor": {
    "id": "ID",
    "displayName": "John Doe",
    "familyName": "Doe",
    "givenName": "John",
    "url": "https://plus.google.com/ID",
    "image": {
     "url": "https://lh5.googleusercontent.com/9HzARk/Cxo/photo.jpg?sz=0"
    }
   },
   "verb": "post",
   "object": {
    "objectType": "note",
    "content": "Sleepy at work",
    "originalContent": "",
    "url": "https://plus.google.com/ID/posts/XgGBBbn",
    "replies": {
     "totalItems": 0,
     "selfLink": "https://www.googleapis.com/plus/v1/activities/xys/comments"
    },
    "plusoners": {
     "totalItems": 0,
     "selfLink": "https://www.googleapis.com/plus/v1/activities/xys/people/plusoners"
    },
    "resharers": {
     "totalItems": 0,
     "selfLink": "https://www.googleapis.com/plus/v1/activities/xys/people/resharers"
    }
   },
   "provider": {
    "title": "Google+"
   },
   "access": {
    "kind": "plus#acl",
    "items": [
     {
      "type": "public"
     }
    ]
   }
  },
  {
  ...
  }
 ]
}

Google+ API 使用包含请求数据的 JSON 提要来响应请求。Google+ 提供了几个有趣的提要,其中包括:

  • 活动提要,包括某个特定用户发布的所有公共帖子。
  • Per-activity 评论提要,包括一系列对某个活动的用户评论。
  • Person 提要,包括一系列用户匹配指定关键字或活动。

上述提要需要使用 API 密钥或 OAuth 令牌进行身份验证。

提要本身的格式为 JSON 文档,最外层的密钥包含提要结果集的标题和当前页面的 URL(以及在适用情况下,下一页和上一页)。items 数组包含一个资源集。根据请求的提要,资源可能是活动、个人资料或评论。集合中的每一项都包含有关资源的详细信息,包括:

  • 资源的公共 URL
  • 资源类型和资源 ID
  • 作者
  • 发布日期

根据资源类型,可能会包含更多信息,比如:活动内容、个人资料描述、作者图像、回复数量、共享和 +1s,或者是附件及其内容。您将在本文后面看到这些内容的示例。

目前,Google+ API 是只读的。您可以从中检索信息,但是目前 API 不支持写操作,比如发布新活动或评论,更新作者信息或照片,或者是删除活动。

在第三方应用程序中使用 Google+ 内容受 Google+ 服务条款的约束。您的应用程序应当遵循 Google+ Developer Policies。在开发前,花几分钟时间阅读一下这些文档是值得的,可确保您遵循所有必要规则(参阅 参考资料)。


检索活动提要

这一节将介绍如何将 Google+ API 返回的数据与 PHP 应用程序集成在一起。最简单的方式是使用 Zend 框架的 Zend_Http_Client 组件,这简化了创建、传输和处理 HTTP 请求的过程。清单 2 显示了如何使用 Zend_Http_Client 将请求传输到 Google+ API 并处理结果。

清单 2. 处理 Google+ 活动提要
<?php
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Http_Client');

// define user ID
$uid = 'YOUR-ID-HERE';

// define API key
$key = 'YOUR-API-KEY-HERE';

try {
  // get feed of user public activities
  // decode JSON response
  $client = new Zend_Http_Client(
    "https://www.googleapis.com/plus/v1/people/$uid/activities/public?key=$key"
  );
  $response = $client->request('GET'); 
  $result = json_decode($response->getBody());

  // iterate through response  
  echo '<h1>' . $result->title . '</h1>';
  echo count($result->items) . ' post(s) found. <br/>';
  echo '<ol>';
  foreach ($result->items as $entry) {
    echo '<li>';
    echo '<a href="' . $entry->url . '">' . $entry->title . '</a>';
    echo ' (' . date("d M Y h:i", strtotime($entry->published)) . ')';  
    echo '</li>';
  }
  echo "</ol>";
  
} catch (Exception $e) {
  echo 'ERROR:' . $e->getMessage();
}   
?>

清单 2 首先加载 Zend 类库并初始化 Zend_Http_Client 类的实例。对于 API 端点 https://www.googleapis.com/plus/v1/people/[ID]/activities/public 的用户公共活动提要,您可以使用此客户端创建并传输 GET 请求(如 清单 1 所示)。注意,本例中的端点 URL 必须包含用户的 Google ID 和 Google API 的控制台生成的 API 密钥。

然后系统会解析该请求的 JSON 响应,并使用 PHP 的 json_decode() 函数将它转换为 PHP 对象,如 图 3 所示。

图 3. 包含 Google+ 活动内容的 PHP 对象
包含 Google+ 活动内容的 PHP 对象

如果您将 图 3 中的对象属性与 清单 1 中的 JSON 文档键值对进行比较,就会看到两者之间的对应关系。现在,进行下列操作非常简单:迭代对象中的 items 数组,检索各个活动的数据(比如活动标题、帖子 URL 和发布日期),以及格式化此数据并以 Web 页面的形式显示它。

图 4 显示了您可能看到的输出的示例。

图 4. 显示了 Google+ 活动帖子的 Web 页面
显示了 Google+ 活动帖子的 Web 页面

检索活动内容和附件

清单 1 中的原始活动提要包括每个帖子的额外信息,包括有关视频或照片等嵌入资源的元数据。知道了这一点后,您就可以完善 清单 2,提取此额外信息并显示它们,如 清单 3 所示。

清单 3. 显示 Google+ 活动提要的额外数据和嵌入资源
<!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>Extracting data from a public activity feed</title>
    <style>
    table {
      border-collapse: yes;      
    }
    .photo {
      vertical-align: top;
    }
    td.divider {
      border-bottom: dashed silver 1px;
    }
    </style>
  </head>
		 <body>  
<?php
// load Zend classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Http_Client');

// define user ID
$uid = 'YOUR-ID-HERE';

// define API key
$key = 'YOUR-API-KEY-HERE';

try {
  // get feed of user public activities
  // decode JSON response
  $client = new Zend_Http_Client(
    "https://www.googleapis.com/plus/v1/people/$uid/activities/public?key=$key"
  );
  $response = $client->request('GET'); 
  $result = json_decode($response->getBody());

  // iterate through response  
  echo '<h1>' . $result->title . ' - ' . count($result->items) . 
    ' post(s) found</h1>';
  echo '<table>';
  foreach ($result->items as $entry) {
    echo '<tr>';
    echo '<td class="photo"><img src="' . $entry->actor->image->url . 
      '" /><br/>';  
    echo '<a href="' . $entry->actor->url . '">'. 
      $entry->actor->displayName . '</a></td><td>';
    if (!empty($entry->title)) {
      echo '<a href="' . $entry->url . '">' . $entry->title . 
        '</a> <br/>';
    }
    if (count($entry->object->attachments)) {
      foreach ($entry->object->attachments as $a) {
        switch ($a->objectType) {
          case 'article':
            echo '<a href="' . $a->url . '">Article: ' . 
              $a->displayName . '</a><br/>';
            break;
          case 'photo':
            echo '<a href="'.$a->fullImage->url.'"><img src="' . 
              $a->image->url . '" /> </a><br/>';
            break;
          case 'video':
            echo '<a href="' . $a->url . '">Video: ' . $a->displayName . 
              '</a><br/><img src="' . $a->image->url . 
              '" /><br/>';
            break;
        }
      }
    }
    echo 'Posted on ' . date("d M Y h:i", strtotime($entry->published));      
    echo '</td></tr><tr><td class=divider colspan=2>
      </td></tr>';
  }
  echo '</table>';  


  } catch (Exception $e) {
  echo 'ERROR:' . $e->getMessage();
}   
?>
  </body>
</html>

清单 3清单 2 更进一步。对于每个帖子,清单 3 都会检索作者的姓名和照片,并将它们与帖子内容一同显示。对于包含其他嵌入附件(比如图像、视频或外部链接)的帖子来说,它会迭代每个条目包含的 attachments 数组,并在帖子内容下方显示相应的资源。图 5 显示了一个输出的示例。

图 5. 显示 Google+ 帖子和附件的 Web 页面
显示 Google+ 帖子和附件的 Web 页面

下面的 清单 4 创建了 清单 3 的一个更加交互式的版本,方法是允许用户输入活动 ID 并查看该活动的详细信息。清单 4 使用一个不同的 API 端点 https://www.googleapis.com/plus/v1/activities/[ID],它必须传递一个活动 ID 并以单条 JSON 记录的形式返回活动的全部详细信息。

清单 4. 交互式表单,显示 Google+ 活动提要的内容
<!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>Retrieving activity details</title>
    <style>
    table {
      border-collapse: yes;      
    }
    .photo {
      vertical-align: top;
    }
    td.divider {
      border-bottom: dashed silver 1px;
    }
    .meta {
      font-style: italic;
    }    
    </style>
  </head>
  <body>  
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for activity by ID: <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_Http_Client');

      // define API key
      $key = 'YOUR-API-KEY-HERE';

      $aid = $_POST['q']; 
      
      try {
        // get user public feed
        // decode JSON response
        $client = new Zend_Http_Client(
          "https://www.googleapis.com/plus/v1/activities/$aid?key=$key"
        );
        $response = $client->request('GET'); 
        $entry = json_decode($response->getBody());
        
        // iterate through response  
        // print fields
        echo '<h1>' . $entry->title . '</h1>';
        echo '<table>';
        echo '<tr>';
        echo '<td class="photo"><img src="' . 
          $entry->actor->image->url . '" /></td><td>';  
        if (!empty($entry->title)) {
          echo '<a href="' . $entry->url . '">' . $entry->title . 
            '</a> <br/>';
        }
        if (count($entry->object->attachments)) {
          foreach ($entry->object->attachments as $a) {
            switch ($a->objectType) {
              case 'article':
                echo '<a href="' . $a->url . '">Article: ' . 
                  $a->displayName . '</a><br/>';
                break;
              case 'photo':
                echo '<a href="'.$a->fullImage->url.'"><img src="' . 
                  $a->image->url . '" /> </a><br/>';
                break;
              case 'video':
                echo '<a href="' . $a->url . '">Video: ' . 
                  $a->displayName . '</a><br/><img src="' . 
                  $a->image->url . '" /><br/>';
                break;
            }
          }
        }
        echo '<div class="meta">Posted on ' . 
          date("d M Y h:i", strtotime($entry->published)) . ' by <a href="' . 
          $entry->actor->url . '">'. $entry->actor->displayName . 
          '</a> <br/>';
        echo 'Replies: ' . (int)$entry->replies->totalItems . 
          ' | +1s: ' . (int)$entry->plusoners->totalItems . 
          ' | Reshares: ' . (int)$entry->resharers->totalItems . 
          '</div>';
        echo '</td></tr></table>';
        
      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();
      }   
    }
    ?>
  </body>
</html>

清单 4 添加了一个输入表单,并允许用户输入活动 ID。然后,连接到 Google+ API 端点并以 JSON 文档的形式检索活动的完整记录。这会将它转化为 PHP 对象,并对它进行格式化以便显示它,操作方式类似于 清单 3清单 4 使用每个帖子附加的额外元数据,比如回复的数量、重新共享的次数和每个帖子吸引的 +1s。如果您想知道如何获得开始使用的活动 ID,则需要从活动 JSON 文档中提取它。

图 6 显示了一个输出示例。

图 6. 显示了 Google+ 帖子和附件的 Web 页面
显示了 Google+ 帖子和附件的 Web 页面

检索用户信息

与检索用户清单一样,您可以检索用户信息。首先,您需要获取目标用户的 Google ID,并在对 API 端点(位于 https://www.googleapis.com/plus/v1/people/[ID])的调用中包含它。生成的 JSON 响应包含有关用户的个人信息,包括全名、照片、简介和 URL(只要可用)。

清单 5 说明了这一过程。

清单 5. 交互式表单,检索 Google+ 用户信息
<!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>Retrieving user profiles</title>
    <style>
    table {
      border-collapse: yes;      
    }
    .photo {
      vertical-align: top;
    }
    td.divider {
      border-bottom: dashed silver 1px;
    }
    </style>
  </head>
  <body>  
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for user by ID: <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_Http_Client');

      // define API key
      $key = 'YOUR-API-KEY-HERE';
      
      $uid = $_POST['q'];

      try {
        // get user public feed
        // decode JSON response
        $client = new Zend_Http_Client(
          "https://www.googleapis.com/plus/v1/people/$uid?key=$key"
        );
        $response = $client->request('GET'); 
        $result = json_decode($response->getBody());
        
        // iterate through response  
        // print fields
        echo '<h1><img src="' . $result->image->url. '" />' . 
          $result->displayName . '</h1>';
        echo isset($result->tagline) ? '<h2>' . $result->tagline . 
          '</h1>' : '';
        echo isset($result->aboutMe) ? $result->aboutMe . '<br/>' : '';
        if (isset($result->urls) && count($result->urls)) {
        echo '<h3>Links</h3> <ul>';
        foreach ($result->urls as $u) {
          $label = '';
          if ($u->type == 'json') continue;
          if ($u->type == 'profile') $label = 'Google+ Profile: ';
          echo '<li><a href="'. $u->value . '">' . $label . 
            $u->value . '</a></li>';
        }
        echo '</ul>';
        }  
          
      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();
      }   
    }
    ?>
  </body>
</html>

清单 5清单 4 类似,它请求用户的 Google ID,然后连接到 API 以检索有关用户的信息。响应通常(至少)包括用户的姓名和照片 URL(或默认照片,如果没有提供照片的话) 。如果用户输入了有关自己的更多信息,则会在 JSON 响应中包含此信息。与之前一样,可以将响应转换为 PHP 对象并对其进行格式化,以便在浏览器中显示它们。

图 7 显示了 清单 5 的输出的示例。

图 7. 显示了 Google+ 用户信息的 Web 页面
显示了 Google+ 用户信息的 Web 页面

搜索活动流

除了检索单个公共提要或用户信息外,您还可以通过 Google+ API 使用关键字搜索活动提要。此 API 方法(位于 https://www.googleapis.com/plus/v1/activities endpoint)接受 query 参数,该参数包含一个或多个要搜索的关键字。清单 6 演示了 PHP 应用程序上下文中的 API。

清单 6. 通过关键字搜索活动
<!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>
    table {
      border-collapse: yes;      
    }
    .photo {
      vertical-align: top;
    }
    td.divider {
      border-bottom: dashed silver 1px;
    }
    </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_Http_Client');

      // define API key
      $key = 'YOUR-API-KEY-HERE';
      
      try {
        if (empty($_POST['q'])) {
          throw new Exception('No search term provided');  
        }
        
        // search all feeds
        $url = "https://www.googleapis.com/plus/v1/activities?key=$key&query=" . 
          urlencode($_POST['q']);
        $client = new Zend_Http_Client($url);
        $response = $client->request('GET'); 
        $result = json_decode($response->getBody());

        // iterate through returned feed  
        // display results
        echo '<h1>' . $result->title . ' - ' . 
          count($result->items) . ' post(s) found</h1>';
        echo '<table>';
        foreach ($result->items as $entry) {
          echo '<tr>';
          echo '<td class="photo"><img src="' . 
            $entry->actor->image->url . '" /><br/>';  
          echo '<a href="' . $entry->actor->url . '">'. 
            $entry->actor->displayName . '</a></td><td>';
          if (!empty($entry->title)) {
            echo '<a href="' . $entry->url . '">' . $entry->title . 
              '</a> <br/>';
          }
          if (count($entry->object->attachments)) {
            foreach ($entry->object->attachments as $a) {
              switch ($a->objectType) {
                case 'article':
                  echo '<a href="' . $a->url . '">Article: ' . 
                    $a->displayName . '</a><br/>';
                  break;
                case 'photo':
                  echo '<a href="'.$a->fullImage->url.'"><img src="' . 
                    $a->image->url . '" /> </a><br/>';
                  break;
                case 'video':
                  echo '<a href="' . $a->url . '">Video: ' . $a->displayName . 
                    '</a><br/><img src="' . $a->image->url . 
                    '" /><br/>';
                  break;
              }
            }
          }
          echo 'Posted on ' . date("d M Y h:i", strtotime($entry->published));      
          echo '</td></tr><tr>
            <td class=divider colspan=2></td></tr>';
        }
        echo '</table>';  
      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();
      }              
    }
    ?>
  </body>
</html>

清单 6 生成了一个 Web 表单,该 Web 表单包含一个输入字段,用户可以在此输入一个或多个关键字。提交了表单后,会创建一个新 Zend_Http_Client 实例,并且会将用户的输入调入 API 端点的 GET 请求中。然后,会将 JSON 响应转换为 PHP 对象,以便对其进行进一步的处理。

图 8 显示了 清单 6 生成的输出示例。

图 8. 通过关键字搜索 Google+ 活动的 Web 表单
通过关键字搜索 Google+ 活动的 Web 表单

默认情况下,Google+ API 返回的每个结果集都包含 10 个条目。您可以强迫 API 返回不同数量的结果,方法是将 maxResults 参数添加到 API 请求,并将值指定在 1 和 20 之间。API 返回的每个 JSON 文档还包含一个 nextPageToken 属性,可以将该属性添加到查询字符串,以检索结果集的下一页,从而启用数据集分页。


搜索用户信息

您可以使用 Google+ API 通过关键字搜索人员。此方法的 API 端点是 https://www.googleapis.com/plus/v1/people。与活动搜索 API 一样,API 端点接受一个包含关键字的 query 参数,并在该参数中查找关键字。

清单 7 修改了 清单 6 已搜索人员而不是活动。

清单 7. 根据用户信息搜索活动
<!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;      
      width: 100%;
    }
    .photo {
      vertical-align: top;
    }
    .posts td:not(:last-child) {
      border-bottom: dashed silver 1px;
    }
    td.divider {
      border-bottom: solid green 2px;    
    }
    td.post {
      padding-bottom: 20px;
    }
    .meta {
      font-style: italic;
    }
    </style>     
  </head>
  <body>  
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for people by name: <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_Http_Client');

      // define API key
      $key = 'YOUR-API-KEY-HERE';
      
      try {
        if (empty($_POST['q'])) {
          throw new Exception('No search term provided');  
        }
        
        // search all feeds
        $url = "https://www.googleapis.com/plus/v1/people?key=$key&query=" . 
          urlencode($_POST['q']);
        $client = new Zend_Http_Client($url);
        $response = $client->request('GET'); 
        $result = json_decode($response->getBody());

        // iterate through returned feed  
        // display results
        echo '<h1>' . $result->title . ' - ' . count($result->items) . 
          ' user(s) found</h1>';
        echo '<table>';
        foreach ($result->items as $entry) {
          echo '<tr>';
          echo '<td class="photo"><img src="' . $entry->image->url . 
            '" /><br/>';  
          echo '<a href="' . $entry->url . '">'. $entry->displayName . 
            '</a></td><td>';
          
          // get user's three most recent public posts
          $client->setUri("https://www.googleapis.com/plus/v1/people/" . 
            $entry->id . "/activities/public?key=$key&maxResults=3");
          $response = $client->request('GET'); 
          $result2 = json_decode($response->getBody()); 
          echo '<table class="posts">';
          foreach ($result2->items as $entry2) {
            echo '<tr><td class="post">';
            if (!empty($entry2->title)) {
              echo '<a href="' . $entry2->url . '">' . 
                $entry2->title . '</a> <br/>';
            }
            if (count($entry2->object->attachments)) {
              foreach ($entry2->object->attachments as $a) {
                switch ($a->objectType) {
                  case 'article':
                    echo '<a href="' . $a->url . '">Article: ' . 
                      $a->displayName . '</a><br/>';
                    break;
                  case 'photo':
                    echo '<a href="'.$a->fullImage->url.'"><img src="' . 
                      $a->image->url . '" /> </a><br/>';
                    break;
                  case 'video':
                    echo '<a href="' . $a->url . '">Video: ' . 
                      $a->displayName . '</a><br/><img src="' . 
                      $a->image->url . '" /><br/>';
                    break;
                }
              }
            }
            echo '<span class="meta">Posted on ' . 
              date("d M Y h:i", strtotime($entry2->published)) . '</span>';      
            echo '</td></tr>';
          }
          echo '</table>';
          echo '</td></tr><tr>
            <td class=divider colspan=2></td></tr>';
        }
        echo '</table>';
      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();
      }              
    }
    ?>
  </body>
</html>

清单 7 非常有趣,因为它实际上是使用两个 API 方法调用的。首先,它查询位于 https://www.googleapis.com/plus/v1/people 的 API 端点,搜索与指定关键字匹配的用户信息。然后,它迭代生成的集合。对于每条匹配的信息,检索用户的 Google ID,将用户 ID 纳入对 API 端点(位于 https://www.googleapis.com/plus/v1/people/[ID]/activities/public)的第二次请求中,以检索用户最近发布的 3 篇帖子。与 清单 6 一样,每个帖子都随附提供了相应嵌入资源(比如图像、视频或外部文章)的链接。

清单 7 的结果与 图 9 类似。

图 9. 用于根据关键字搜索 Google+ 用户信息的 Web 表单
用于根据关键字搜索 Google+ 用户信息的 Web 表单

检索活动评论

Google+ 支持用户发布包含信息、照片、视频和链接的活动,并允许其他用户对这些活动发表评论。您可以通过每个活动的评论提要查看评论内容,评论提要位于 API 端点 https://www.googleapis.com/plus/v1/activities/[ID]/comments。清单 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>Retrieving comments</title>
    <style>
    table {
      border-collapse: yes;      
    }
    .photo {
      vertical-align: top;
    }
    td.divider {
      border-bottom: dashed silver 1px;
    }
    .meta {
      font-style: italic;
    }
    </style>
  </head>
  <body>  
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for comments on activity (enter activity ID): 
      <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_Http_Client');

      // define API key
      $key = 'YOUR-API-KEY-HERE ';

      $aid = $_POST['q']; 
      
      try {
        // get activity feed
        // decode JSON response
        $client = new Zend_Http_Client(
          "https://www.googleapis.com/plus/v1/activities/$aid?key=$key"
        );
        $response = $client->request('GET'); 
        $entry = json_decode($response->getBody());
        
        // iterate through response  
        // print fields
        echo '<h1>' . $entry->title . '</h1>';
        echo '<table>';
        echo '<tr>';
        echo '<td class="photo"><img src="' . 
          $entry->actor->image->url . '" /></td><td>';  
        if (!empty($entry->title)) {
          echo '<a href="' . $entry->url . '">' . $entry->title . 
            '</a> <br/>';
        }
        if (count($entry->object->attachments)) {
          foreach ($entry->object->attachments as $a) {
            switch ($a->objectType) {
              case 'article':
                echo '<a href="' . $a->url . '">Article: ' . 
                  $a->displayName . '</a><br/>';
                break;
              case 'photo':
                echo '<a href="'.$a->fullImage->url.'"><img src="' . 
                  $a->image->url . '" /> </a><br/>';
                break;
              case 'video':
                echo '<a href="' . $a->url . '">Video: ' . $a->displayName . 
                  '</a><br/><img src="' . $a->image->url . '" /><br/>';
                break;
            }
          }
        }
        echo '<div class="meta">Posted on ' . 
          date("d M Y h:i", strtotime($entry->published)) . ' by <a href="' . 
          $entry->actor->url . '">'. $entry->actor->displayName . 
          '</a> <br/>';
        echo 'Replies: ' . (int)$entry->replies->totalItems . 
          ' | +1s: ' . (int)$entry->plusoners->totalItems . 
          ' | Reshares: ' . (int)$entry->resharers->totalItems . 
          '</div>';
        echo '</td></tr></table>';
        
        // get comments feed for activity
        $client->setUri(
          "https://www.googleapis.com/plus/v1/activities/$aid/comments?key=$key"
        );
        $response = $client->request('GET'); 
        $result = json_decode($response->getBody());
        
        // iterate through response  
        // print fields
        if (count($result->items)) {
          echo '<h3>' . $result->title . '</h3>';
          echo '<ul>';
          foreach ($result->items as $comment) {        
            echo '<li>' . $comment->object->content . 
              '<br/>';
            echo '<span class="meta">Posted on ' . 
              date("d M Y h:i", strtotime($comment->published)) . 
              ' by <a href="' . $comment->actor->url . '">'. 
              $comment->actor->displayName . '</a> </span>';
            echo '</li>';
          }
          echo '</ul>';
        }

      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();
      }   
    }
    ?>
  </body>
</html>

清单 8 的第一部分与 清单 4 类似。它的焦点是接受用户输入 Web 表单的活动 ID 并连接到 API,以检索并显示该活动的详细信息。然后,脚本对活动的评论提要进行第二次 API 调用,这会返回一个 JSON 文档,包含其他用户针对该活动发布的所有评论。将解析此 JSON 文档,并将每条评论的内容,以及发布时间和发帖人的姓名添加到页面中。

图 10 显示了输出。

图 10. 显示了 Google+ 活动和评论的 Web 页面
显示了 Google+ 活动和评论的 Web 页面

结束语

在撰写本文时,Google+ API 仍然是一个相对较新的产品,并且仅支持只读操作。但是,与您从本文的示例了解到的一样,它仍然提供了几个将公共 Google+ 内容集成到任何 Web 应用程序的选项。我们期待 Google+ API 更加成熟,随着 Google+ 服务在作用域上的扩展而提供更多的功能。那时,创建混搭或构建 Google+ 自定义界面将会非常简单。祝您编码愉快!

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=XML, Open source
ArticleID=831938
ArticleTitle=利用 PHP 应用程序搜索并集成 Google+ 活动流
publish-date=08272012