【问题标题】:How Upload large files to Onedrive using PHP-Curl如何使用 PHP-Curl 将大文件上传到 Onedrive
【发布时间】:2018-05-22 08:06:00
【问题描述】:

我需要将大于 4MB 的文件上传到 onedrive 帐户。我正在为此尝试使用 PHP 和 curl。有没有人尝试过这个选项,请帮我解决这个问题。

【问题讨论】:

  • 你没有告诉我们问题,或者分享任何代码???

标签: php api curl onedrive


【解决方案1】:

$url='https://graph.microsoft.com/v1.0/me/drive/root:/filename:/createUploadSession';

    $data= '{}';
    $header = array('Content-Type: json',
        "Cache-Control: no-cache",
        "Pragma: no-cache",
        "Authorization: bearer {Access Token}");
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header );
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

从结果中获取uploadURL,

    $graph_url = $result['uploadUrl'];
    $fragSize = 320 * 1024;
    $file = file_get_contents($filename_location);
    $fileSize = strlen($file);
    $numFragments = ceil($fileSize / $fragSize);
    $bytesRemaining = $fileSize;
    $i = 0;
    $ch = curl_init($graph_url);
    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($filename_location, '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"
        );
        curl_setopt($ch, CURLOPT_URL, $graph_url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, constant('CURL_SSL_VERIFYPEER_STATUS'));
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $server_output = curl_exec($ch);
        $info = curl_getinfo($ch);

        $bytesRemaining = $bytesRemaining - $chunkSize;
        $i++;
    }

当您传递最后一组数据时,它应该是正确的数据字节。否则上传会话将失败。

【讨论】:

    【解决方案2】:

    您的应用程序需要:

    • 创建上传会话
    • 将字节上传到上传会话

    请参阅 OneDrive 开发中心的上传带有上传会话文档的大文件页面:https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createuploadsession#create-an-upload-session,详细了解每个步骤的请求类型以及预期的 JSON 或 http 响应代码。

    从 PHP 功能的角度来看,您希望:

    1. 确定上传文件的属性(文件大小、文件名)
    2. 通过 curl 发送帖子数据以创建上传会话(请参阅标题为 SEND POST FROM CURL in this blog post 的部分以获取 #1 的示例代码 sn-p。)
    3. 将上面的 JSON 响应中的 uploadUrl 解析为 php 变量
    4. 通过 cURL 将二进制内容发送到上面提取的 uploadURL(请参阅标题为 Send the binary contents via cURL in this blog post 的部分(发送整个文件或部分块 - 应考虑文件大小和连接/带宽来确定方法)李>
    5. 解析响应头(http响应代码)并有条件地:
      • 如果失败则使用预期的字节范围重试(HTTP 416 Requested Range Not Satisfiable 的响应代码)
      • 如果传输字节范围/部分,则继续下一个字节范围(202 Accepted 的响应代码) - 请参阅“恢复正在进行的上传”
      • 完成/返回/退出功能(HTTP 200 OKHTTP 201 Created 的响应代码)
      • 在任何 50x 响应中,发送 GET 请求(请参阅“恢复正在进行的上传”)以确定接下来要发送什么/如何恢复

    如果检测到文件名冲突(响应码HTTP/1.1 409 Conflict):

    1. Send a DELETE request using curl command取消上传会话(你应该得到HTTP/1.1 204 No Content的响应代码。
    2. 解决/处理名称冲突
    3. 重启进程

    【讨论】:

      【解决方案3】:

      这段代码对我有用:

      <?php
      
      $fileName="myfile.zip";
      $filename_location=realpath($fileName);
      
      $token="{access token}";
      $ch = curl_init();
      $url="https://graph.microsoft.com/v1.0/me/drive/root:/api/$fileName:/createUploadSession";
      curl_setopt($ch, CURLOPT_URL,$url );
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
      $data= '{
          "item": {
              "@microsoft.graph.conflictBehavior": "rename",
              "description": "description",
              "fileSystemInfo": { "@odata.type": "microsoft.graph.fileSystemInfo" },
              "name": "'.$fileName.'"
        }
      }';
          $header = array(
              'Content-Type: application/json',
              "Cache-Control: no-cache",
              "Pragma: no-cache",
              "Authorization: bearer $token");
              curl_setopt($ch, CURLOPT_URL, $url);
              curl_setopt($ch, CURLOPT_POST, TRUE);
              curl_setopt($ch, CURLOPT_HTTPHEADER, $header );
              curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
              curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
      
      $result = json_decode(curl_exec($ch)) ;
      
      
      $graph_url = $result->uploadUrl;
      
      
          $fragSize = 320 * 1024;
          $file = file_get_contents($filename_location);
          $fileSize = strlen($file);
          $numFragments = ceil($fileSize / $fragSize);
          $bytesRemaining = $fileSize;
          $i = 0;
          $ch = curl_init($graph_url);
          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($filename_location, '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"
              );
              curl_setopt($ch, CURLOPT_URL, $graph_url);
              curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
              curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
              curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
              curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
              curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
              $server_output = curl_exec($ch);
              $info = curl_getinfo($ch);
              $bytesRemaining = $bytesRemaining - $chunkSize;
              $i++;
          }
      
      ?>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-25
        • 1970-01-01
        相关资源
        最近更新 更多