PHP、Guzzle、Microsoft Graph API、文件块、大文件上传会话不断失败-如何修复?
我试图使用微软图形API使用PHP上传大文件。根据MS文档,您必须将其拆分为块。当我使用下面的代码时,它似乎一直在上传,直到最后一块。。在最后一个块之后,它失败了。我到底做错了什么,为什么会出现下面提到的错误。我是否必须为最后一块包含某种逻辑?或者我还遗漏了什么 错误详细信息: PHP致命错误:uncaughtguzzlehttp\Exception\RequestException:cURL错误56:OpenSSL SSL\u读取:SSL\u错误\u系统调用,错误号54(请参阅)PHP、Guzzle、Microsoft Graph API、文件块、大文件上传会话不断失败-如何修复?,php,api,microsoft-graph-api,guzzle,Php,Api,Microsoft Graph Api,Guzzle,我试图使用微软图形API使用PHP上传大文件。根据MS文档,您必须将其拆分为块。当我使用下面的代码时,它似乎一直在上传,直到最后一块。。在最后一个块之后,它失败了。我到底做错了什么,为什么会出现下面提到的错误。我是否必须为最后一块包含某种逻辑?或者我还遗漏了什么 错误详细信息: PHP致命错误:uncaughtguzzlehttp\Exception\RequestException:cURL错误56:OpenSSL SSL\u读取:SSL\u错误\u系统调用,错误号54(请参阅) 由于内容范围
由于
内容范围
标题的最后一个字节范围在此处计算不正确,因此最有可能发生这种错误:
if ($end > $fileNbByte) {
$end = $fileNbByte;
}
相反,它应该是这样的:
if ($end > $fileNbByte) {
$end = $fileNbByte + 1;
}
这是一个经过修改(且更通用)的版本,应按预期工作:
/**
* @param Graph $graph Graph client
* @param string $siteId site Id
* @param string $itemId item Id
* @param string $inputPath input path for a file
* @param int $chunkSize chunk size
* @throws GraphException
*/
function uploadLargeFile($graph,$siteId,$itemId,$inputPath,$chunkSize)
{
$fileName = basename($inputPath);
/** @var UploadSession $uploadSession */
$uploadSession = $graph->createRequest("POST",
"/sites//$siteId/drive/items/$itemId:/$fileName:/createUploadSession")
->addHeaders(["Content-Type" => "application/json"])
->attachBody([
"item" => [
"@microsoft.graph.conflictBehavior" => "replace",
]
])
->setReturnType(UploadSession::class)
->execute();
$handle = fopen($inputPath, 'rb');
$fileSize = fileSize($inputPath);
$prevBytesRead = 0;
while (!feof($handle)) {
$bytes = fread($handle, $chunkSize);
$bytesRead = ftell($handle);
$resp = $graph->createRequest("PUT", $uploadSession->getUploadUrl())
->addHeaders([
'Connection' => "keep-alive",
'Content-Length' => ($bytesRead-$prevBytesRead),
'Content-Range' => "bytes " . $prevBytesRead . "-" . ($bytesRead-1) . "/" . $fileSize,
])
->setReturnType(UploadSession::class)
->attachBody($bytes)
->execute();
$prevBytesRead = $bytesRead;
}
fclose($handle);
}
用法
/**
* @param Graph $graph Graph client
* @param string $siteId site Id
* @param string $itemId item Id
* @param string $inputPath input path for a file
* @param int $chunkSize chunk size
* @throws GraphException
*/
function uploadLargeFile($graph,$siteId,$itemId,$inputPath,$chunkSize)
{
$fileName = basename($inputPath);
/** @var UploadSession $uploadSession */
$uploadSession = $graph->createRequest("POST",
"/sites//$siteId/drive/items/$itemId:/$fileName:/createUploadSession")
->addHeaders(["Content-Type" => "application/json"])
->attachBody([
"item" => [
"@microsoft.graph.conflictBehavior" => "replace",
]
])
->setReturnType(UploadSession::class)
->execute();
$handle = fopen($inputPath, 'rb');
$fileSize = fileSize($inputPath);
$prevBytesRead = 0;
while (!feof($handle)) {
$bytes = fread($handle, $chunkSize);
$bytesRead = ftell($handle);
$resp = $graph->createRequest("PUT", $uploadSession->getUploadUrl())
->addHeaders([
'Connection' => "keep-alive",
'Content-Length' => ($bytesRead-$prevBytesRead),
'Content-Range' => "bytes " . $prevBytesRead . "-" . ($bytesRead-1) . "/" . $fileSize,
])
->setReturnType(UploadSession::class)
->attachBody($bytes)
->execute();
$prevBytesRead = $bytesRead;
}
fclose($handle);
}
$graph = new Graph();
$token = getAccessToken($tenantId,$clientId,$clientSecret);
$graph->setAccessToken($token->access_token);
$chunkSize = 1024 * 1024;
uploadLargeFile($graph,$siteId,$itemId,$localPath,$chunkSize);