如何解决PHP+OAuth2上传SharePoint时的ID3035格式错误?
以下是针对你的代码和错误的具体排查点及修复方案:
1. 文档库名称的URL编码问题
你的文档库名称「Plan de Trabajo」包含空格,直接拼接在API URL中会触发格式错误。需要对文档库名称进行URL编码后再传入getbytitle方法。
2. 文件名与本地文件不匹配
代码中$file_name设置为mi-archivo.pdf,但实际上传的本地文件是Azul.jpg,虽然这不是ID3035的直接原因,但会导致上传后文件类型混乱,建议保持两者一致。
3. Content-Length计算不准确
使用strlen($file_content)统计二进制文件长度可能出错,因为strlen按字符数计算,而二进制文件应使用filesize($file_path)获取准确字节大小。
4. 缺少必要的请求头
SharePoint REST API需要明确指定Accept: application/json头,否则可能返回非预期响应格式,导致请求被判定为无效。
5. 凭据变量的多余空格
你的client_id和client_secret变量末尾带有空格,会导致认证失败,需去掉这些空格。
修改后的完整代码
// SharePoint站点URL $site_url = 'https://usbbogedu.sharepoint.com/vacademica'; // 文档库名称 $library_name = 'Plan de Trabajo'; // 对含空格的文档库名称进行URL编码 $encoded_library_name = rawurlencode($library_name); // 上传后的文件名(与本地文件保持一致) $file_name = 'Azul.jpg'; // 本地文件路径 $file_path = '../subida_sp/Azul.jpg'; // OAuth2认证信息 $client_id = 'client_id'; // 去掉末尾空格 $client_secret = 'client_secret'; // 去掉末尾空格 $tenant_id = 'tenant_id'; $resource = 'https://usbbogedu.sharepoint.com'; // 获取OAuth2访问令牌 $auth_url = "https://login.microsoftonline.com/$tenant_id/oauth2/token"; $ch = curl_init($auth_url); $data = array( 'grant_type' => 'client_credentials', 'client_id' => $client_id, 'client_secret' => $client_secret, 'resource' => $resource ); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); if (false == $response) { echo "获取OAuth2令牌失败\n"; die(curl_error($ch)); } $token_data = json_decode($response, true); // 增加令牌获取失败的判断 if (!isset($token_data['access_token'])) { echo "令牌获取失败: " . $response . "\n"; die(); } $token = $token_data['access_token']; // SharePoint API请求URL(使用编码后的文档库名称) $url = $site_url . "/_api/web/lists/getbytitle('$encoded_library_name')/RootFolder/Files/add(url='$file_name',overwrite=true)"; // 读取本地文件内容 $file_content = file_get_contents($file_path); if ($file_content === false) { echo "读取本地文件失败\n"; die(); } // 请求头设置 $headers = array( 'Authorization: Bearer ' . $token, 'Content-Type: application/octet-stream', 'Content-Length: ' . filesize($file_path), // 使用filesize获取准确文件大小 'Accept: application/json;odata=verbose' // 添加必要的Accept头 ); // 发送上传请求 $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $file_content); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 开启SSL验证(生产环境建议保持开启) curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); $response = curl_exec($ch); if (false == $response) { echo "上传请求失败\n"; $info = curl_getinfo($ch); foreach($info as $key => $value){ echo "$key: $value <br>"; } echo "Curl错误信息: " . curl_error($ch) . "<br>"; } else { echo "响应内容: ". $response ."\n"; $data = json_decode($response); if (json_last_error() !== JSON_ERROR_NONE) { echo "响应不是有效JSON格式\n"; } } curl_close($ch);
额外检查项
- 确认Azure AD应用已被授予Sites.FullControl.All应用权限,并完成了管理员同意。
- 验证
$site_url指向的站点确实存在且可访问。 - 检查本地文件路径是否正确,PHP进程是否有读取该文件的权限。
内容的提问来源于stack exchange,提问作者jaison dario bejarano valdes
相关产品推荐
相关产品推荐

