1

I would like to upload a file from an url to google drive chunked but I am getting an error. I've tested it with a local file and it works. What's wrong with this?

Here's my code:

<?php
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/GoogleApi.php';

if (php_sapi_name() != 'cli') {
    throw new Exception('This application must be run on the command line.');
}

/**
 * Get a chunk of a file.
 *
 * @param resource $handle
 * @param int      $chunkSize
 *
 * @return string
 */
function readFileChunk($handle, int $chunkSize) {
    $byteCount = 0;
    $giantChunk = '';
    while (!feof($handle)) {
        $chunk = fread($handle, 8192);
        $byteCount += strlen($chunk);
        $giantChunk .= $chunk;
        if ($byteCount >= $chunkSize) {

            return $giantChunk;
        }
    }

    return $giantChunk;
}

/**
 * Get Remote File Size
 *
 * @param string $url
 *
 * @return int
 */
function remoteFileSize($url) {
    # Get all header information
    $data = get_headers($url, true);
    # Look up validity
    if (isset($data['Content-Length'])) {
        return (int) $data['Content-Length'];
    }

    return 0;
}

/**
 * Get Remote File Size
 *
 * @param string $url
 *
 * @return string
 */
function remoteMimeType($url) {
    $ext = pathinfo($url, PATHINFO_EXTENSION);
    $mimeType = 'application/octetstream';

    switch ($ext) {
        case 'zip'    :
            $mimeType = 'application/zip';
            break;
        case 'rar'    :
            $mimeType = 'application/x-rar-compressed';
            break;
        case '7z'    :
            $mimeType = 'application/x-7z-compressed';
            break;
    }

    return $mimeType;
}

/**
 * Upload a file to the google drive.
 */
try {
    $googleApi = new GoogleApi();
    $client = $googleApi->getClient();
    $service = new Google_Service_Drive($client);
    $getFile = new Google_Service_Drive_DriveFile();
    $url = 'http://ipv4.download.thinkbroadband.com/1MB.zip';
    $getFile->name = 'Test File.zip';
    $chunkSizeBytes = 0.5 * 1024 * 1024;

    // Call the API with the media upload, defer so it doesn't immediately return.
    $client->setDefer(true);
    $request = $service->files->create($getFile);

    // Get file mime type
    $mimeType = remoteMimeType($url);

    // Create a media file upload to represent our upload process.
    $media = new Google_Http_MediaFileUpload(
        $client,
        $request,
        $mimeType,
        null,
        true,
        $chunkSizeBytes
    );
    $media->setFileSize(remoteFileSize($url));

    // Upload the various chunks. $status will be false until the process is
    // complete.
    $status = false;

    $handle = fopen($url, 'rb');
    while (!$status && !feof($handle)) {
        // read until you get $chunkSizeBytes from TESTFILE
        // fread will never return more than 8192 bytes if the stream is read buffered and it does not represent a plain file
        // An example of a read buffered file is when reading from a URL
        $chunk = readFileChunk($handle, $chunkSizeBytes);
        $status = $media->nextChunk($chunk);
    }

    // The final value of $status will be the data from the API for the object that has been uploaded.
    $uploadedFileId = '';
    if ($status !== false) {
        $uploadedFileId = $status['id'];
        print_r($uploadedFileId);
    } else {
        throw new Exception('Upload failed');
    }

    fclose($handle);
} catch (Exception $e) {
    print 'An error occurred: ' . $e->getMessage();
}
Vic
  • 21,473
  • 11
  • 76
  • 97
Joshua Ott
  • 1,143
  • 10
  • 12
  • 2
    What is status? That message is yours not Googles so is there a file on drive? – Linda Lawton - DaImTo May 20 '17 at 12:04
  • 1
    @DaImTo Thanks for the fast answer! $status is false and no file is on the drive after upload is finished. – Joshua Ott May 21 '17 at 12:24
  • 1
    If I understood your issue correctly, try `resumable` or `multipart` to upload files by chunks. You can also see a code implementation sample in this related [SO post](http://stackoverflow.com/a/24638243/5995040). Hope this helps. – Mr.Rebot May 21 '17 at 21:33
  • 1
    @Mr.Rebot It's already a resumable file upload but it doesn't work (it works with a local file but not with a remote url). $media->nextChunk($chunk) returns false although the file upload is complete. – Joshua Ott May 22 '17 at 17:59

0 Answers0