PHP实现无交互连接Google Drive API,用于Cron定时备份任务
实现无交互的Google Drive API上传(适配Cron任务)
要让PHP脚本能在Cron任务里自动执行、完全无需用户交互,你得改用**服务账号(Service Account)**认证方式——这是Google API专为后台无人值守任务设计的方案。下面是具体的实现步骤和修改后的代码:
第一步:创建服务账号并获取密钥文件
- 登录Google Cloud控制台,找到你的现有项目(或新建一个项目)
- 在API库中搜索并启用「Google Drive API」
- 进入「IAM与管理」→「服务账号」,点击「创建服务账号」
- 填写名称和ID后直接完成创建(暂时不需要分配项目角色,后续手动设置Drive权限即可)
- 找到刚创建的服务账号,进入「密钥」标签页,点击「添加密钥」→「创建新密钥」,选择JSON格式下载密钥文件(保存为
service-account-key.json,放到你的PHP项目目录)
第二步:给服务账号分配Drive文件夹权限
服务账号有独立的Drive存储空间,你需要把目标上传文件夹共享给服务账号的邮箱:
- 打开Google Drive,找到你原代码中
$servername对应的文件夹 - 右键点击文件夹→「共享」,输入服务账号的邮箱(在你下载的JSON密钥文件里的
client_email字段),至少分配「编辑」权限,保存设置
第三步:修改PHP代码为服务账号认证版本
替换你原来的手动OAuth认证代码,改成以下无交互版本:
<?php require_once 'google-api-php-client/vendor/autoload.php'; /* 配置项 */ $servername = '你的目标文件夹名称'; // 替换成你原代码中的文件夹名称 $backupFilePath = '/path/to/your/backup/file.sql'; // 替换成你的备份文件实际路径 $serviceAccountKeyPath = 'service-account-key.json'; // 服务账号密钥文件路径 // 初始化Google客户端 $client = new Google_Client(); $client->setAuthConfig($serviceAccountKeyPath); $client->addScope(Google_Service_Drive::DRIVE); // 服务账号自动获取令牌,无需用户交互 $client->fetchAccessTokenWithAssertion(); $drive = new Google_Service_Drive($client); // 查找目标父文件夹($servername对应的文件夹) $parentFolderId = null; $files = $drive->files->listFiles([ "q" => "name = '{$servername}' and mimeType = 'application/vnd.google-apps.folder'", "fields" => "files(id, name)" ])->getFiles(); foreach ($files as $file) { $parentFolderId = $file->getId(); break; // 取第一个匹配的文件夹即可 } if (!$parentFolderId) { die("未找到名为{$servername}的目标文件夹,请检查共享权限是否正确"); } // 创建当日备份文件夹(按需保留) $today = date('Y-m-d'); $todayFolderMeta = new Google_Service_Drive_DriveFile([ 'name' => $today, 'mimeType' => 'application/vnd.google-apps.folder', 'parents' => [$parentFolderId] ]); $todayFolder = $drive->files->create($todayFolderMeta, [ 'fields' => 'id' ]); $todayFolderId = $todayFolder->getId(); // 上传备份文件到当日文件夹 $fileMetadata = new Google_Service_Drive_DriveFile([ 'name' => basename($backupFilePath), 'parents' => [$todayFolderId] ]); $media = new Google_Http_MediaFileUpload( $client, $fileMetadata, mime_content_type($backupFilePath), file_get_contents($backupFilePath) ); $uploadedFile = $drive->files->create($fileMetadata, [ 'data' => $media, 'uploadType' => 'multipart', 'fields' => 'id' ]); echo "备份文件上传成功,文件ID:{$uploadedFile->getId()}"; ?>
代码关键说明:
- 彻底移除了
$_SESSION和重定向相关代码,服务账号认证完全在后台自动完成 - 用
fetchAccessTokenWithAssertion()替代手动OAuth流程,自动获取访问令牌 - 补充了完整的文件上传逻辑(你原代码仅创建了文件夹)
- 增加了基础错误检查,方便排查问题
第四步:测试脚本并设置Cron任务
- 先手动测试:在服务器终端执行
php /path/to/your/upload-script.php,确认文件能成功上传到Drive - 设置定时任务(比如每天凌晨2点执行):
- 编辑Cron任务:
crontab -e - 添加一行:
0 2 * * * php /path/to/your/upload-script.php >> /var/log/drive-backup.log 2>&1 - 这会每天凌晨2点自动执行脚本,同时把日志输出到
/var/log/drive-backup.log方便后续排查
- 编辑Cron任务:
内容的提问来源于stack exchange,提问作者sdfgg45
相关产品推荐
相关产品推荐

