正在检索域中所有 Google 日历资源中的 XML?

Retrieving XML of all Google Calendar Resources on a domain?

我目前正在 PHP 中处理一个表格,该表格将合并两项不同的任务:为活动预订 space,以及为在线日历注册活动。我用 PHP 的 API 客户端确定了 Google 日历片段,但 Calendar Resources 仍然是个问题。

以下是关于我目前所在位置的一些信息:

我目前的困境涉及我从通话中 return 收集的数据。当我使用 Google OAuth2 Playground 通过上述 URI 发出请求时,它会毫无问题地检索 XML 数据。当我在 PHP 中进行相同的尝试时,我得到了具有以下格式的单个字符串中的数据:

我知道每次请求只会return每次请求100个资源,而且游乐场和我的phpreturn好像都是100个条目,所以没有出现必然是授权问题。话虽这么说,但我不确定我在操场上的做法会有所不同。

我的 cURL 请求如下(一旦检索到 access_token):

$url = 'https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/';

$token = json_decode($_SESSION['access_token'], true);
$access_token = $token['access_token'];
$token_type = $token['token_type'];

//open connection
$ch = curl_init();

curl_setopt_array($ch, array(
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_URL => $url,
    CURLOPT_HTTPHEADER => array('Authorization: '.$token_type.' '.$access_token,),
));

// $output contains the returned data
$output = curl_exec($ch);

if($output === false) { echo 'Curl error: ' . curl_error($ch); }
else { echo $output; }

// close curl resource to free up system resources
curl_close($ch);   

是否有我遗漏的 cURL 设置或 header?我猜不出它会是什么,尤其是当 Playground 的请求如下时:

GET /a/feeds/calendar/resource/2.0/domain/ HTTP/1.1
Host: apps-apis.google.com
Content-length: 0
Authorization: Bearer access_token

更新

Hans Z. 的回答促使我(谢谢!)寻找将 XML 数据放入数组的方法,因为我需要使用获得的数据而不是显示它。 (我很抱歉最初没有说清楚。)There are a lot of posts on the subject,在通过 SimpleXML 输出后,我检索了以下内容作为每个资源 (x100) 的条目:

[0] => SimpleXMLElement Object
(
    [id] => https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621
    [updated] => 2015-02-18T17:04:16.481Z
    [link] => Array
    (
        [0] => SimpleXMLElement Object
        (
            [@attributes] => Array
            (
                [rel] => self
                [type] => application/atom+xml
                [href] => https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621
            )
        )

        [1] => SimpleXMLElement Object
        (
            [@attributes] => Array
            (
                [rel] => edit
                [type] => header('Content-type: application/xml');
                [href] => https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621
            )
        )
    )
)

如上所示,这不会提供有关资源本身的任何信息,例如名称或电子邮件(或 ID,以任何直接 parse-less 方式)。我通过 SimpleXML 尝试了 运行 playground 的 XML 输出,并且正在恢复完全相同的输出。假设它与 SimpleXML 相关,我进行了更多搜索并找到了 this question, this question, and this blog post。我本人一直在研究他们的建议,但迄今为止收效甚微。如果有人想在我之前解决这个问题(因为我今天剩下的大部分时间都必须参加会议),这里有一个 XML 结构的例子:

<feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:apps='http://schemas.google.com/apps/2006'>
    <id>https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain</id>
    <updated>2015-02-18T17:03:03.057Z</updated>
    <link rel='next' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/?start=579841149621'/>
    <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain'/>
    <link rel='http://schemas.google.com/g/2005#post' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain'/>
    <link rel='self' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain'/>
    <openSearch:startIndex>1</openSearch:startIndex>

    <entry>
        <id>https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621</id>
        <updated>2015-02-18T17:03:03.056Z</updated>
        <link rel='self' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621'/>
        <link rel='edit' type='application/atom+xml' href='https://apps-apis.google.com/a/feeds/calendar/resource/2.0/domain/579841149621'/>

        <apps:property name='resourceId' value='579841149621'/>
        <apps:property name='resourceCommonName' value='Projector'/>
        <apps:property name='resourceEmail' value='domain_key@resource.calendar.google.com'/>
    </entry>

    //99 more times:
    <entry>
        ...
    </entry>

您的脚本运行良好,但您正在浏览器中查看脚本的输出。浏览器将尝试将 XML 输出解析为 HTML,从而得出观察到的结果。更改您的代码,使其向浏览器指示响应为 XML,如下所示:

header('Content-type: application/xml');
if($output === false) { echo 'Curl error: ' . curl_error($ch); }
else { echo $output; }

或者使用命令行 PHP 解释器查看输出。

编辑:

您可能更乐意在 PHP 中解析 JSON;您可以通过将 alt=json 添加到请求中来获得 JSON 中的结果,如:

https://apps-apis.google.com/a/feeds/calendar/resource/2.0/<domain>/?alt=json

并将 $output = json_decode($output) 应用于输出;然后您可以访问所需的数据,例如第一个资源的邮箱地址,如下:

$output->feed->entry[0]->{'apps$property'}[2]->value 

以下是 Hans Z. 为那些宁愿将资源作为数组处理的人提供的替代解决方案:

$array = json_decode($output, true);
$resources = $array['feed']['entry'];

foreach ($resources as $resource) {
    $id = $resource['apps$property']['0']['value'];
    $name = $resource['apps$property']['1']['value'];
    $email = $resource['apps$property']['2']['value'];

    //do something with data
}