如何在无人工干预的情况下通过PHP向OneDrive上传文件?
无交互自动上传文件至组织OneDrive的PHP实现方案
核心思路:使用Azure AD客户端凭据流
要实现完全无人工干预的自动化上传,必须采用Azure AD客户端凭据授权流(Client Credentials Flow),这是专为服务端到服务端无用户交互场景设计的,无需跳转登录页或浏览器介入。
前置准备
- 在Azure AD中注册应用程序:
- 获取租户ID、客户端ID(Application ID)、客户端密钥(Client Secret)
- 为应用添加应用权限(而非委派权限):
Files.ReadWrite.All,并由组织管理员完成权限同意
- 确定目标OneDrive的Graph API端点:
- 上传到组织站点文档库:
https://graph.microsoft.com/v1.0/sites/{site-id}/drive/root:/{目标路径}/{文件名}:/content - 上传到特定用户的OneDrive:
https://graph.microsoft.com/v1.0/users/{user-id}/drive/root:/{目标路径}/{文件名}:/content
- 上传到组织站点文档库:
方案一:使用Microsoft Graph PHP SDK
1. 安装SDK依赖
composer require microsoft/microsoft-graph
2. 无交互上传代码实现
<?php require __DIR__ . '/vendor/autoload.php'; use Microsoft\Graph\Graph; use Microsoft\Graph\Model\DriveItem; use League\OAuth2\Client\Provider\GenericProvider; // 配置参数 $tenantId = '你的租户ID'; $clientId = '你的客户端ID'; $clientSecret = '你的客户端密钥'; $targetFilePath = '/文档库目录/测试上传文件.txt'; // OneDrive内的目标路径 $localFilePath = '/本地文件路径/test.txt'; // 待上传的本地文件 // 初始化OAuth凭据提供者 $oauthProvider = new GenericProvider([ 'clientId' => $clientId, 'clientSecret' => $clientSecret, 'urlAuthorize' => "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/authorize", 'urlAccessToken' => "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token", 'urlResourceOwnerDetails' => '', 'scopes' => 'https://graph.microsoft.com/.default' ]); // 获取访问令牌 $accessToken = $oauthProvider->getAccessToken('client_credentials'); // 初始化Graph客户端 $graph = new Graph(); $graph->setAccessToken($accessToken->getToken()); // 读取本地文件内容 $fileContent = file_get_contents($localFilePath); // 执行上传 try { $driveItem = $graph->createRequest('PUT', "/sites/{site-id}/drive/root:$targetFilePath:/content") ->attachBody($fileContent) ->setReturnType(DriveItem::class) ->execute(); echo "文件上传成功,ID: " . $driveItem->getId(); } catch (Exception $e) { echo "上传失败:" . $e->getMessage(); } ?>
方案二:纯HTTP请求实现
1. 获取访问令牌
<?php $tenantId = '你的租户ID'; $clientId = '你的客户端ID'; $clientSecret = '你的客户端密钥'; $tokenUrl = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"; $postData = [ 'grant_type' => 'client_credentials', 'client_id' => $clientId, 'client_secret' => $clientSecret, 'scope' => 'https://graph.microsoft.com/.default' ]; $ch = curl_init($tokenUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']); $response = curl_exec($ch); curl_close($ch); $tokenData = json_decode($response, true); $accessToken = $tokenData['access_token'] ?? ''; if (empty($accessToken)) { die("获取令牌失败:" . ($tokenData['error_description'] ?? '未知错误')); } ?>
2. 上传文件到OneDrive
<?php $targetFilePath = '/文档库目录/测试上传文件.txt'; $localFilePath = '/本地文件路径/test.txt'; $graphEndpoint = "https://graph.microsoft.com/v1.0/sites/{site-id}/drive/root:$targetFilePath:/content"; $fileContent = file_get_contents($localFilePath); $ch = curl_init($graphEndpoint); curl_setopt($ch, CURLOPT_PUT, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Authorization: Bearer $accessToken", "Content-Type: application/octet-stream" ]); curl_setopt($ch, CURLOPT_POSTFIELDS, $fileContent); $uploadResponse = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode === 201 || $httpCode === 200) { echo "文件上传成功"; } else { echo "上传失败,状态码:$httpCode,响应:$uploadResponse"; } ?>
关键注意事项
- 必须使用应用权限,委派权限强制要求用户交互,不符合无干预场景
- 组织管理员必须对应用权限完成管理员同意,否则会触发权限不足错误
- 上传超过4MB的大文件时,需采用分片上传方式,调用Graph API的上传会话接口
- 确保服务器环境支持PHP cURL扩展或SDK依赖的HTTP客户端
内容的提问来源于stack exchange,提问作者Dillon Diego Pillay
相关产品推荐
相关产品推荐

