使用PHP SDK处理大文件的Microsoft Graph API文件上传仍然失败

时间:2018-11-15 07:32:20

标签: php upload microsoft-graph onedrive

我目前正在使用microsoft-php-sdk,效果非常好。我设法将小文件从服务器上传到OneDrive。但是,当我尝试上传38MB Powerpoint文件时,它失败了。 Microsoft Graph API文档建议创建一个上传会话。我认为这就像将URI从 / content 更新为/ createUploadSession 一样容易,但是仍然失败。

$response = $graph->createRequest('POST', '/me/drive/root/children/'.basename($path).'/createUploadSession')
      ->setReturnType(Model\DriveItem::class)
      ->upload($path);

我的代码看起来像这样。我很难弄清PHP SDK文档,也没有上传会话的示例。以前有人在这种情况下使用过PHP SDK吗?

4 个答案:

答案 0 :(得分:1)

我不熟悉PHP,但是我熟悉上载API。希望这会有所帮助。

您之前使用的/content端点允许您直接将二进制内容写入文件,并按代码预期返回DriveItem/createUploadSession方法的工作方式有所不同。 resumable upload的Graph文档对此进行了详细说明,但我将在此处进行总结。

  1. 您可以发送空的正文,也可以发送带有元数据的JSON负载(例如文件名或解决冲突的行为),而不是发送CreateUploadSession请求中的二进制内容。
  2. CreateUploadSession的响应是一个UploadSession对象,而不是DriveItem。该对象具有uploadUrl属性,可用于发送二进制数据。
  3. 使用HTTP Content-Range标头在多个请求上上传二进制数据,以指示要上传的字节范围。
  4. 服务器收到文件的最后一个字节后,上传将自动完成。

尽管此概述说明了基础知识,但您应该编写一些其他概念。例如,如果您的字节范围之一无法上传,则需要询问服务器它已经拥有的字节范围以及在哪里恢复。这些以及其他内容在文档中都有详细说明。 https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/driveitem_createuploadsession

答案 1 :(得分:1)

我已经基于Microsoft graph rest api为oneDrive开发了一个类似的库。这个问题也可以在这里解决:tarask/oneDrive

查看上传大文件部分

中的文档

答案 2 :(得分:0)

pip install xgboost-0.6-cp35-cp35m-win_amd64.whl

这对我有用!

答案 3 :(得分:0)

我在https://github.com/microsoftgraph/msgraph-sdk-php/wiki和laravel框架中使用了类似的方法。这是最终对我有用的代码。

public function test()
{
    //initialization
    $viewData = $this->loadViewData();

    // Get the access token from the cache
$tokenCache = new TokenCache();
$accessToken = $tokenCache->getAccessToken();

// Create a Graph client
$graph = new Graph();
$graph->setAccessToken($accessToken);
//upload larger files
// 1. create upload session
        $fileLocation = 'S:\ebooks\myLargeEbook.pdf';


         $file =  \File::get($fileLocation);
            $reqBody=array(
    "@microsoft.graph.conflictBehavior"=> "rename | fail | replace",
    "description"=> "description",
    "fileSystemInfo"=> ["@odata.type"=> "microsoft.graph.fileSystemInfo"]  ,
        "name"=> "ebook.pdf",
      );
        $uploadsession=$graph->createRequest("POST", "/drive/root:/test/ebook.pdf:/createUploadSession")
        ->attachBody($reqBody)
        ->setReturnType(Model\UploadSession::class)
        ->execute();
//2. upload bytes
        $fragSize =320 * 1024;// 1024 * 1024 * 4;
        $fileLocation = 'S:\ebooks\myLargeEbook.pdf';
// check if exists file if not make one
    if (\File::exists($fileLocation)) {
$graph_url = $uploadsession->getUploadUrl();
        $fileSize = filesize($fileLocation);
$numFragments = ceil($fileSize / $fragSize);
        $bytesRemaining = $fileSize;
        $i = 0;
while ($i < $numFragments) {
            $chunkSize = $numBytes = $fragSize;
            $start = $i * $fragSize;
            $end = $i * $fragSize + $chunkSize - 1;
            $offset = $i * $fragSize;
            if ($bytesRemaining < $chunkSize) {
                $chunkSize = $numBytes = $bytesRemaining;
                $end = $fileSize - 1;
            }
            if ($stream = fopen($fileLocation, 'r')) {
                // get contents using offset
                $data = stream_get_contents($stream, $chunkSize, $offset);
                fclose($stream);
            }
$content_range = "bytes " . $start . "-" . $end . "/" . $fileSize;
$headers = array(
                "Content-Length"=> $numBytes,
                "Content-Range"=> $content_range
            );
$uploadByte = $graph->createRequest("PUT", $graph_url)
            ->addHeaders($headers)
            ->attachBody($data)
                ->setReturnType(Model\UploadSession::class)
                ->setTimeout("1000")
                ->execute();
$bytesRemaining = $bytesRemaining - $chunkSize;
            $i++;
        }

    }
    dd($uploadByte);
           }
}