You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP调用Google Calendar API批量插入事件失败求助

解决Google Calendar API批量插入事件的PHP报错问题

嘿,我懂你遇到的困扰了——单个事件插入正常,批量操作就报错,问题出在你用错了Google Calendar API的批量处理方式!

你当前调用的是单个事件创建接口(/calendars/{calendarId}/events),这个接口只接受单个事件对象作为请求体,但你传了一个包含items数组的结构,API自然没法识别,所以报错。要实现批量插入,得用Google API的批量请求(Batch Requests),下面给你两种可行的方案:

方案一:用Google官方PHP客户端库(强烈推荐)

官方库已经帮你封装好了批量请求的复杂逻辑,不用自己手动处理multipart格式,省心很多。

步骤1:安装客户端库

先通过composer安装:

composer require google/apiclient:^2.0

步骤2:改写批量插入代码

require __DIR__ . '/vendor/autoload.php';

function batchCreateCalendarEvents($calendarId, $accessToken, $events) {
    // 初始化客户端并设置token
    $client = new Google\Client();
    $client->setAccessToken($accessToken);
    
    // 创建Calendar服务实例
    $calendarService = new Google\Service\Calendar($client);
    
    // 初始化批量请求对象
    $batch = new Google\Http\Batch($client);
    
    // 把每个事件添加到批量请求里
    foreach ($events['items'] as $eventData) {
        $event = new Google\Service\Calendar\Event($eventData);
        // 每个请求加个唯一标识,方便后续处理结果
        $batch->add(
            $calendarService->events->insert($calendarId, $event),
            uniqid()
        );
    }
    
    // 执行批量请求
    $results = $batch->execute();
    
    // 提取所有成功插入的事件ID
    $eventIds = [];
    foreach ($results as $response) {
        if ($response instanceof Google\Service\Calendar\Event) {
            $eventIds[] = $response->getId();
        }
    }
    
    return $eventIds;
}

// 你的事件数据(和原来一样)
$calendar = json_decode(' { "summary": "Calendar name", "description": "Calendar description", "items": [ { "summary": "event1", "colorId": "10", "start": { "dateTime": "2018-05-10T12:30:00+02:00" }, "end": { "dateTime": "2018-05-10T13:30:00+02:00" }, "recurrence": [ "RRULE:FREQ=WEEKLY;COUNT=13;BYDAY=TH" ] }, { "summary": "event2", "start": { "dateTime": "2018-05-17T12:30:00+02:00" }, "end": { "dateTime": "2018-05-17T13:30:00+02:00" } }, { "summary": "event3", "description": "event3 description", "colorId": "2", "start": { "date": "2018-05-10" }, "end": { "date": "2018-05-11" }, "transparency": "transparent" } ] } ', true);

// 调用函数并处理结果
try {
    $eventIds = batchCreateCalendarEvents('primary', $_SESSION['access_token'], $calendar);
    echo "批量插入成功!事件ID:" . implode(', ', $eventIds);
} catch (Exception $e) {
    echo "出错啦:" . $e->getMessage();
}

方案二:手动实现批量请求(不用composer)

如果不想安装第三方库,可以手动构造multipart格式的请求,直接调用批量API端点:

function batchCreateCalendarEvents($calendarId, $accessToken, $events) {
    $batchUrl = 'https://www.googleapis.com/batch/calendar/v3';
    // 生成唯一的分隔符,用于区分多个子请求
    $boundary = 'batch_' . uniqid();
    
    $payload = '';
    // 遍历每个事件,构造子请求
    foreach ($events['items'] as $index => $eventData) {
        $eventJson = json_encode($eventData);
        $payload .= "--{$boundary}\r\n";
        $payload .= "Content-Type: application/http\r\n";
        $payload .= "Content-ID: <item{$index}>\r\n\r\n";
        $payload .= "POST /calendar/v3/calendars/{$calendarId}/events HTTP/1.1\r\n";
        $payload .= "Content-Type: application/json\r\n\r\n";
        $payload .= "{$eventJson}\r\n";
    }
    // 结束符
    $payload .= "--{$boundary}--\r\n";
    
    // 初始化curl
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $batchUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer ' . $accessToken,
        'Content-Type: multipart/mixed; boundary=' . $boundary
    ]);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode != 200) {
        throw new Exception("批量插入失败,HTTP状态码:{$httpCode},响应内容:{$response}");
    }
    
    // 解析响应,提取事件ID
    $eventIds = [];
    $parts = explode("--{$boundary}", $response);
    foreach ($parts as $part) {
        if (strpos($part, '200 OK') !== false && strpos($part, '"id":') !== false) {
            preg_match('/"id":"([^"]+)"/', $part, $matches);
            if (isset($matches[1])) {
                $eventIds[] = $matches[1];
            }
        }
    }
    
    return $eventIds;
}

// 调用方式和方案一一致
try {
    $eventIds = batchCreateCalendarEvents('primary', $_SESSION['access_token'], $calendar);
    echo "批量插入成功!事件ID:" . implode(', ', $eventIds);
} catch (Exception $e) {
    echo "出错啦:" . $e->getMessage();
}

最后再强调下原因

你原来的函数调用的是单个事件接口,请求体必须是单个Event对象,但你传的是包含items数组的结构,API无法解析,所以报错。另外要确保你的access_token有https://www.googleapis.com/auth/calendar的权限,不然也会失败哦。

内容的提问来源于stack exchange,提问作者Ok Ram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:35:24