Как я могу загрузить файлы в GoogleDrive в «многочастном» виде с помощью Guzzle? - PullRequest
1 голос
/ 24 марта 2020

С помощью @Tanaike (см. здесь ) я могу успешно загрузить файлы в GoogleDrive с помощью php -curl, вот мой код с помощью php -curl:

function uploadByCurl($uploadFilePath, $accessToken){
    $ch = curl_init();
    $boundary = md5(mt_rand() . microtime());
    //MetaData
    $params = json_encode([
        'name' => basename($uploadFilePath),
        'description' => 'This is a test',
    ]);
    $fileContent = file_get_contents($uploadFilePath);

    $dataToUpload = "--{$boundary}\r\n";
    $dataToUpload .= "Content-Type: application/json\r\n\r\n";
    $dataToUpload .= "{$params}\r\n";
    $dataToUpload .= "--{$boundary}\r\n";
    $dataToUpload .= "Content-Transfer-Encoding: base64\r\n\r\n";
    $dataToUpload .= base64_encode($fileContent) . "\r\n";
    $dataToUpload .= "--{$boundary}--";

    $options = [
        CURLOPT_URL =>  'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart',
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POSTFIELDS => $dataToUpload,
        CURLOPT_HTTPHEADER => [
            'Authorization:Bearer ' . $accessToken,
            'Content-Type: multipart/related; boundary=' . $boundary,
        ],
        //In case you're in Windows, sometimes will throw error if not set SSL verification to false
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => 0,
    ];
    //In case you need a proxy
    //$options[CURLOPT_PROXY] = 'http://127.0.0.1:1087';

    curl_setopt_array($ch, $options);
    $result = curl_exec($ch);
    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    }
    curl_close ($ch);
    return $result;
}

$uploadFilePath = '<YOU-FILE-ABS-PATH>';
$accessToken = '<YOU-ACCESS-TOKEN>';
$ret = uploadByCurl($uploadFilePath, $accessToken);
var_dump($ret);

Ответ json:

{
 "kind": "drive#file",
 "id": "1lkuCTeMooRmde8uzNa7COUTTCLAk_jdq",
 "name": "timg (12).jpeg",
 "mimeType": "image/jpeg"
}

Но когда я пытаюсь использовать Guzzle6 (клиент curl, написанный PHP), чтобы сделать то же самое, файл (файл изображения) может быть успешно загружен, но его имя «Без названия», и я не могу просмотреть изображение (см. скриншот ниже):

enter image description here

enter image description here

Вот мой фрагмент кода с использованием Guzzle:

function uploadByGuzzle($uploadFilePath, $accessToken){
    $boundary = md5(mt_rand() . microtime());
    //MetaData
    $params = json_encode([
        'name' => basename($uploadFilePath),
        'description' => 'This is a test',
    ]);
    $fileContent = file_get_contents($uploadFilePath);

    $dataToUpload = "--{$boundary}\r\n";
    $dataToUpload .= "Content-Type: application/json\r\n\r\n";
    $dataToUpload .= "{$params}\r\n";
    $dataToUpload .= "--{$boundary}\r\n";
    $dataToUpload .= "Content-Transfer-Encoding: base64\r\n\r\n";
    $dataToUpload .= base64_encode($fileContent) . "\r\n";
    $dataToUpload .= "--{$boundary}--";

    $GuzzleConfig = [
        'base_uri' => 'https://www.googleapis.com/upload/drive/v3/files/',
        'timeout'  => 30.0,
    ];
    //In case you need a proxy
    $GuzzleConfig['proxy'] = 'http://127.0.0.1:1087';
    //GuzzleHttp
    $client = new Client($GuzzleConfig);
    $uri = '?uploadType=multipart';
    $response = $client->request('POST', $uri, [
        'verify' => false,
        'headers' => [
            'Authorization' => 'Bearer ' . $accessToken,
            'Content-Type' => 'Content-Type: multipart/related; boundary=' . $boundary,
        ],
        'body' => $dataToUpload,
    ]);

    $string = $response->getBody()->getContents();
    return $string;
}

$uploadFilePath = '<YOU-FILE-ABS-PATH>';
$accessToken = '<YOU-ACCESS-TOKEN>';
$ret = uploadByGuzzle($uploadFilePath, $accessToken);
var_dump($ret);

1 Ответ

1 голос
/ 25 марта 2020

Я думаю, что тело запроса верное. В вашем скрипте Content-Type не правильно. В этом случае я думаю, что body отправляется как application/octet-stream. Таким образом, создается файл Untitled. И я думаю, что это текстовые данные тела запроса.

Так как насчет этой модификации?

От:

'Content-Type' => 'Content-Type: multipart/related; boundary=' . $boundary,

Кому:

'Content-Type' => 'multipart/related; boundary=' . $boundary,
...