Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP、Guzzle、Microsoft Graph API、文件块、大文件上传会话不断失败-如何修复?_Php_Api_Microsoft Graph Api_Guzzle - Fatal编程技术网

PHP、Guzzle、Microsoft Graph API、文件块、大文件上传会话不断失败-如何修复?

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(请参阅) 由于内容范围

我试图使用微软图形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);