如何使用PHP-Curl将大文件上传到Onedrive

时间:2017-12-08 05:24:11

标签: php api curl onedrive

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

3 个答案:

答案 0 :(得分:3)

$网址=' https://graph.microsoft.com/v1.0/me/drive/root:/filename:/createUploadSession&#39 ;;

    $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++;
    }

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

答案 1 :(得分:2)

您的申请需要:

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

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

从PHP功能的角度来看,您需要:

  1. 确定上传文件的属性(文件大小,文件名)
  2. 通过curl发送帖子数据以创建上传会话(有关#1的示例代码段,请参阅标题为SEND POST FROM CURL in this blog post的部分。)
  3. 将uploadUrl从上面的JSON响应解析为php变量
  4. 通过cURL将二进制内容发送到上面提取的uploadURL(参见标题为Send the binary contents via cURL in this blog post的部分(要么发送整个文件,要么在部分块中,文件大小和连接/带宽应该被考虑在内以确定方法)
  5. 有条理地解析响应头(http响应代码):
    • 如果失败则返回预期的字节范围(HTTP 416请求范围的响应代码不可满足)
    • 如果发送字节范围/部分(响应代码为202 Accepted),
    • 继续下一个字节范围 - 请参阅&#34;恢复正在进行的上传&#34;
    • 完成/退出/退出功能(响应代码HTTP 200 OKHTTP 201 Created
    • 对任何50x响应,发送GET请求(请参阅&#34;恢复正在进行的上传&#34;)以确定下一步发送内容/如何恢复
  6. 如果检测到文件名冲突(响应代码为HTTP/1.1 409 Conflict):

    1. Send a DELETE request using curl command取消上传会话(您应该获得HTTP/1.1 204 No Content的回复代码。
    2. 解决/处理名称冲突
    3. 重新启动流程

答案 2 :(得分:0)

此代码对我有用:

<?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++;
    }

?>