Этот тип ошибки, скорее всего, возникает, поскольку последний диапазон байтов для заголовка Content-Range
рассчитывается здесь неправильно:
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);
}
Использование
$graph = new Graph();
$token = getAccessToken($tenantId,$clientId,$clientSecret);
$graph->setAccessToken($token->access_token);
$chunkSize = 1024 * 1024;
uploadLargeFile($graph,$siteId,$itemId,$localPath,$chunkSize);