net-tools/google-api

用于访问Google API的Composer库


README

PHP接口,用于访问Google API

此包包含

  • 一些服务助手,用于主Google产品,如日历、驱动器或Gmail等

设置说明

要安装net-tools/google-api包,只需通过composer要求:require net-tools/google-api:^1.0.0。

为了使用此库中的类,请仔细阅读此文档,因为您必须首先设置Google开发账户。还需要了解Google API的基本知识。

Google应用程序凭据和授权过程的概述

注意

Google API可能一开始有点令人困惑,特别是应用程序凭据(只需进行一次)和授权过程(对每个API请求进行一次)的初始设置。

我强烈建议您在阅读以下内容之前,从Google开发者参考中阅读有关这些主题的任何参考资料(例如,https://developers.google.com/identity/protocols/OAuth2WebServerhttps://developers.google.com/google-apps/calendar/auth以进行日历服务授权)。

识别您的应用程序(应用程序凭据)

通过PHP请求Google API需要您的应用程序被“识别”(以便Google可以应用配额)。这样,在用户授予您的应用程序访问其个人Google数据之前,他们可以清楚地识别您的应用程序。

在运行此处任何示例或编写您的应用程序之前,您必须设置Google开发账户(见下文“设置Google开发账户”)。这是强制性的。然后,当您处理API时,您将使用在Google开发账户设置期间获得的凭据来识别您的应用程序。

获取用户数据访问权限(授权过程)

通过PHP请求Google API需要您的应用程序被允许在用户的账户中创建/读取/更新/删除数据。这称为授权过程。根据您请求的授权(API中的“作用域”),您的应用程序可能只被允许读取数据,但不能更新内容。

从您的应用程序,用户将被重定向到Google登录页面,并要求允许访问其个人数据(例如,日历、Gmail等)。如果他接受,他将被重定向回您的应用程序,您的应用程序将获得一个访问令牌,允许1小时内的免费访问(在此延迟之后,用户应再次识别)。您可以将令牌存储在数据库或会话中,以便在此延迟期间重用它。刷新令牌也存在于没有1小时限制的情况(此处不涉及)。

设置您的Google开发账户

设置是通过在Google开发者控制台中注册一个新的应用程序来完成的

  1. 打开Google开发控制台链接:https://console.developers.google.com/
  2. 在左侧,点击凭据
  3. 创建一个新的项目并输入一个名称(一个项目可以包含多个产品,因此要一般化,例如输入您的名字或公司);确认
  4. 在左侧,点击,然后选择要启用的API。在API页面摘要中,点击启用
  5. 为任何其他所需的API重复前面的步骤
  6. 在左侧,点击凭据
  7. 请不要点击创建凭据按钮,因为我们首先需要设置OAuth同意屏幕;打开OAuth同意屏幕选项卡
  8. 请输入产品名称以便用户识别您的应用(他们将允许您的应用访问个人数据,因此清楚地标识您的应用非常重要),然后点击 保存
  9. 现在,您可以点击 创建凭据
  10. 选择 Web 应用;输入您的 Web 应用的名称;输入 授权重定向 URI;这是当用户通过 Google 授权流程后,Google 将用户重定向到的 URL。如果您正在运行这里的某个示例,请输入示例文件的完整路径,包括您的域名。
  11. 点击 创建

此时,请记住屏幕上显示的凭据

  • 您的客户端 ID,
  • 您的客户端密钥。

运行示例

如果您尚未设置 Google 开发者账户,请现在进行设置(请参阅上面的章节)。

要运行示例,请通过开发者控制台输入设置 Google 开发者账户后可用的客户端 ID 和密钥来修改 Credentials.php 中的行。根据您运行的示例,可能需要更多的配置数据,这将在示例文件顶部的注释中说明。

某些示例需要采取一些步骤才能成功运行(例如创建测试事件、联系人、电子邮件),请参阅示例子目录中的相应 Readme 文件。

使用 Google API

以下是一些 Google API 参考链接;在继续阅读之前,您应该阅读这些链接,因为这个包只是 Google API 的前端。您仍然需要使用 Google API。

对于每个 API,不要忘记阅读顶部导航栏上的 指南 部分。

使用此包的类

调用 Google API 至少需要一个对象,称为 Client;许多 Google API 还需要一个第二个对象,称为 Service。您可以将 Client 视为到 API 的连接或接口(“连接”是指通信介质),而 Service 包含业务方法(创建、删除等)。

创建 Client 对象

创建 Client 对象相当简单

$gclient = new Nettools\GoogleAPI\Clients\Serverside_InlineCredentials(
        CLIENT_ID, 
        CLIENT_SECRET, 
        array(\Google\Service\Calendar::CALENDAR_READONLY)
    );

我们创建了一个 Serverside_InlineCredentials 类的对象,使用开发者控制台的凭据来标识应用程序,并请求对用户日历数据的只读访问。它会在后台创建一个 \Google\Client 对象(基础对象,我们创建的对象只是前端)。一些 API 必需参数使用默认值设置(例如,redirectUri 指向脚本 URL)。

如果您更喜欢使用 Json 凭据而不是代码中的字符串来标识,请使用 Serverside_JsonCredentials。如果您正在使用服务帐户,请使用 ServiceAccount。类名中的 ServersideServiceAccount 前缀告诉我们我们正在处理的应用程序类型(请参阅 Google API 以获取有关服务器端或服务帐户的进一步解释)。

如果您已经获得了一个访问令牌,您可以将其传递给构造函数

$gclient = new Nettools\GoogleAPI\Clients\Serverside_InlineCredentials(
        CLIENT_ID, 
        CLIENT_SECRET, 
        array(\Google\Service\Calendar::CALENDAR_READONLY),
        array(
            'accessToken' => $token
        )
    );

或者稍后通过 client 访问器属性调用 setAccessToken() 来设置底层 \Google\Client 对象

$gclient->client->setAccessToken($token);

创建 Service 对象

现在我们已经有了 Client 对象,我们可以使用它来获取特定 API 的 Service 对象

$cal = $gclient->getService('Calendar');
$response = $cal->events->listEvents('primary');

《getService()》方法是从《Clients\GoogleClient》继承的;它创建一个《Service》对象,使得能够对Google服务发起API调用。创建的对象类型取决于几个参数,将在下一章中解释。

服务包装器,此处实现的服务API和Google_Service

根据我们的库是否为目标服务提供服务包装器(例如Gmail或Calendar),以及我们的库是否实现了服务API,getService()将返回一个服务包装器(从ServiceWrappers\ServiceWrapper继承)或来自我们库的服务对象(从Services\Service继承)或直接从Google API库创建的\Google\Service对象。

规则是,如果请求的服务在Google API库中定义,并且我们在库中为其提供了一个服务包装器(如Gmail、Calendar、PeopleService、Drive),则将使用服务包装器。如果没有服务包装器可用,将创建一个来自Google API库的\Google\Service对象。如果请求的服务未在Google API库中实现,我们尝试从我们的库中创建服务对象。

我们的库中的服务包装器提供了一些有用的功能,并充当底层Google API的前端(外观模式)。对于Gmail服务包装器来说这一点非常明显(它实现了对正文部分和附件进行解码的方法)。

如果您请求的服务我们有一个ServiceWrappers\ServiceWrapper对象,那么getService()返回的对象是ServiceWrappers\ServiceWrapper的一个实例。然而,我们的包装器实现了属性和方法调用的转发机制:对于未在包装器中定义的方法的调用将转发到底层的\Google\Service对象。对于属性也是同样的道理。您可以编写

$response = $cal->events->listEvents('primary');
// or explicitely invoke the underlying service object : 
$response = $cal->service->events->listEvents('primary');

错误处理

如果错误来自Google API,将抛出一个\Google\Exception或\Google\Service\Exception。

您需要使用try/catch块捕获异常。\Google\Exception对象的message属性包含错误作为Json字符串。例如,以下是一个无有效凭据的请求的异常消息

{
 "error": {
  "errors": [
   {
    "domain": "usageLimits",
    "reason": "dailyLimitExceededUnreg",
    "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
    "extendedHelp": "https://code.google.com/apis/console"
   }
  ],
  "code": 403,
  "message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
 }
}

您可以提取消息和错误代码

try
{
   ...
}
catch( Google\Service\Exception $e )
{
    $json = json_decode($e->getMessage());
    if ( $json )
        echo "Error code $json->error->code with message $json->error->message";
}