【问题标题】:PHP Upload PDF to Google Drive APIPHP 上传 PDF 到 Google Drive API
【发布时间】:2018-11-11 15:26:36
【问题描述】:

我有一个用 PHP 创建的网站。基本上它是一个发送文件类型的项目。它使用 Azure 中的文档存储,我将调用它并将其发送到 Azure。现在我想发送电子邮件以及存储在 Google 驱动器中。

因此应该将其存储到可供公众访问的驱动器中。我创建了以下代码。它工作正常我不想要用户的任何输入。

  $client->setAccessToken($_SESSION['accessToken']);
    $service = new Google_DriveService($client);
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $file = new Google_DriveFile();
    foreach ($files as $file_name) {
        $file_path = 'files/'.$file_name;
        $mime_type = finfo_file($finfo, $file_path);
        $file->setTitle($file_name);
        $file->setDescription('This is a '.$mime_type.' document');
        $file->setMimeType($mime_type);
        $service->files->insert(
            $file,
            array(
                'data' => file_get_contents($file_path),
                'mimeType' => $mime_type
            )
        );
    }
    finfo_close($finfo);

我想使用 cURL 或 API 从 Azure URL 上传。邮件发送时会同时自动上传到驱动器。

问题更新

我有发送邮件的功能,这是完美的工作。我想将附件存储到谷歌驱动器并检索路径将该路径存储到数据库中。

这一切工作都将基于 API,无需用户交互。该文件是 PDF 格式,而不是特定字节,根据文件数据不同。

问题:

当我将文件上传到云端硬盘时,原始文件名被重命名为无标题。这是代码。

function uploadFile($credentials, $filename, $targetPath)
{

    global $GAPIS;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $GAPIS . 'upload/drive/v2/files?uploadType=media');

    curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
    //curl_setopt($ch, CURLOPT_POSTFIELDS, array("title" =>"newfile.txt"));
    curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents($filename));

    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER,
            array('Content-Type : text/plain', 'Content-Length:' . filesize($filename),
                    'Authorization: Bearer ' . getAccessToken($credentials))
    );

    $postResult = curl_exec($ch);
    curl_close($ch);

    return json_decode($postResult, true);
}

===========================================强>

更新的代码(添加代码的问题,但驱动器中的 Untitle.pdf 仍然存在问题)

===========================================强>

<?php

$GAPIS = 'https://www.googleapis.com/';
$GAPIS_AUTH = $GAPIS . 'auth/';
$GOAUTH = 'https://accounts.google.com/o/oauth2/';

$CLIENT_ID = '709846732498-xxxxxxxx';
$CLIENT_SECRET = 'XXXXXXXXXXXXXX';
$REDIRECT_URI = 'http' . ($_SERVER['SERVER_PORT'] == 80 ? '' : 's') . '://' . $_SERVER['SERVER_NAME'] . $_SERVER['SCRIPT_NAME'];
$SCOPES = array($GAPIS_AUTH . 'drive', $GAPIS_AUTH . 'drive.file', $GAPIS_AUTH . 'userinfo.email', $GAPIS_AUTH . 'userinfo.profile');
$STORE_PATH = 'credentials.json';

function uploadFile($credentials, $filename, $targetPath)
{

    global $GAPIS;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $GAPIS . 'upload/drive/v2/files?uploadType=media');

    curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, file_get_contents($filename));
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER,
            array('Content-Type : application/pdf', 'Content-Length:' . filesize($filename),
                    'Authorization: Bearer ' . getAccessToken($credentials))
    );

    $postResult = curl_exec($ch);
    curl_close($ch);

    return json_decode($postResult, true);
}

function getStoredCredentials($path)
{

    $credentials = json_decode(file_get_contents($path), true);

    if (isset($credentials['refresh_token']))
        return $credentials;

    $expire_date = new DateTime();
    $expire_date->setTimestamp($credentials['created']);
    $expire_date->add(new DateInterval('PT' . $credentials['expires_in'] . 'S'));

    $current_time = new DateTime();

    if ($current_time->getTimestamp() >= $expire_date->getTimestamp())
    {
        $credentials = null;
        unlink($path);
    }

    return $credentials;
}

function storeCredentials($path, $credentials)
{

    $credentials['created'] = (new DateTime())->getTimestamp();
    file_put_contents($path, json_encode($credentials));
    return $credentials;
}

function requestAuthCode()
{

    global $GOAUTH, $CLIENT_ID, $REDIRECT_URI, $SCOPES;
    $url = sprintf($GOAUTH . 'auth?scope=%s&redirect_uri=%s&response_type=code&client_id=%s&approval_prompt=force&access_type=offline',
            urlencode(implode(' ', $SCOPES)), urlencode($REDIRECT_URI), urlencode($CLIENT_ID)
    );
    header('Location:' . $url);
}

function requestAccessToken($access_code)
{

    global $GOAUTH, $CLIENT_ID, $CLIENT_SECRET, $REDIRECT_URI;
    $url = $GOAUTH . 'token';
    $post_fields = 'code=' . $access_code . '&client_id=' . urlencode($CLIENT_ID) . '&client_secret=' . urlencode($CLIENT_SECRET)
            . '&redirect_uri=' . urlencode($REDIRECT_URI) . '&grant_type=authorization_code';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
    curl_setopt($ch, CURLOPT_POST, true);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_URL, $url);

    $result = curl_exec($ch);

    curl_close($ch);

    return json_decode($result, true);
}

function getAccessToken($credentials)
{

    $expire_date = new DateTime();
    $expire_date->setTimestamp($credentials['created']);
    $expire_date->add(new DateInterval('PT' . $credentials['expires_in'] . 'S'));

    $current_time = new DateTime();

    if ($current_time->getTimestamp() >= $expire_date->getTimestamp())
        return $credentials['refresh_token'];
    else
        return $credentials['access_token'];

}

function authenticate()
{

    global $STORE_PATH;

    if (file_exists($STORE_PATH))
        $credentials = getStoredCredentials($STORE_PATH);
    else
        $credentials = null;

    if (!(isset($_GET['code']) || isset($credentials)))
        requestAuthCode();

    if (!isset($credentials))
        $credentials = requestAccessToken($_GET['code']);

    if (isset($credentials) && isset($credentials['access_token']) && !file_exists($STORE_PATH))
        $credentials = storeCredentials($STORE_PATH, $credentials);

    return $credentials;
}

$credentials = authenticate();

$result = uploadFile($credentials, 'example.pdf', '');

if (!isset($result['id']))
    throw new Exception(print_r($result));
else
    echo 'File copied successfuly (file Id: ' . $result['id'] . ')';

echo '<pre>'; print_r($result);

【问题讨论】:

  • 我想我错过了你问题的问题部分。您已经告诉我们您想要做什么,但没有告诉我们您当前的解决方案有什么问题。
  • 需要使用 URL 上传文件到驱动器。没有提交按钮。
  • 您打算从用户的 gmail 帐户中阅读吗?您要将文件上传到谁的云端硬盘帐户?
  • 这是我自己的帐户。首先是上传操作,然后阅读我仍然卡在上传中。
  • 如果您要上传到自己的 Google Drive 帐户,您可以使用 developers.google.com/identity/protocols/OAuth2ServiceAccount。注意:您不能使用服务帐户来读取 gmail。

标签: php azure curl google-api google-api-php-client


【解决方案1】:

通过https://developers.google.com/drive/api/v3/simple-upload,这应该可以工作:

<?php
$ch = curl_init ();
curl_setopt_array ( $ch, array (
        CURLOPT_URL => 'https://www.googleapis.com/upload/drive/v3/files?uploadType=media',
        CURLOPT_HTTPHEADER => array (
                'Content-Type: application/pdf', // todo: runtime detection?
                'Authorization: Bearer [YOUR_AUTH_TOKEN]' 
        ),
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => file_get_contents ( '/path/to/file.pdf' ),
        CURLOPT_RETURNTRANSFER => 1 
) );
try {
    if (false === ($resp = curl_exec ( $ch ))) {
        throw new \RuntimeException ( 'curl error ' . curl_errno ( $ch ) . ": " . curl_error ( $ch ) );
    }
    $parsed = json_decode ( $resp, true );
    if (! $parsed || $parsed ['code'] !== 200) {
        throw new \RuntimeException ( 'google api error: ' . $resp );
    }
} finally{
    curl_close ( $ch );
}
var_dump($resp);

【讨论】:

  • YOUR_AUTH_TOKEN 我找不到这个。
  • @VasimVanzara API 不使用密码,而是使用access tokens,在此处了解如何获取它:developers.google.com/identity/protocols/OAuth2
  • 我已经创建了 Oauth2。是否有可能获得teamviewer?
  • 我有客户端 ID 和客户端创建两个
  • 请提供驱动器中未命名文件的建议。文件已上传,但其名称为 untitled.pdf 或 txt in google drive。
【解决方案2】:

我仍然不能完全确定我理解你的问题。假设您只想在 php 或 curl 中上传文件,这里有两个选项。

上传到 Google 云端硬盘分为两部分,第一部分您创建元数据,即文件名和有关您罚款的基本信息。第二部分是您上传文件实际数据的位置。

$fileMetadata = new Google_Service_Drive_DriveFile(array(
    'name' => 'My Report',
    'mimeType' => 'application/vnd.google-apps.spreadsheet'));
$content = file_get_contents('files/report.csv');
$file = $driveService->files->create($fileMetadata, array(
    'data' => $content,
    'mimeType' => 'text/csv',
    'uploadType' => 'multipart',
    'fields' => 'id'));
printf("File ID: %s\n", $file->id);

media upload 窃取的代码

如果您想在 curl 中执行此操作,插入元数据应该不是问题,您的问题将是上传文件本身。您将需要发布元数据以创建空文件并捕获其文件 ID。然后使用 file-id 进行内容上传。您可以在此处simple upload request 找到有关您需要 dot 提出的请求的更多信息。

代码可能看起来像这样,但您必须再次传递文件 ID。

curl 
--silent 
--request POST 
--data-binary "@c:\temp\myfile.jpg"         
-OL MyFolder\myfile2.jpeg
-H "Slug: myfile3.jpg" 
-H "Authorization: Bearer [your access token here]" 
-H "Content-Type: image/jpeg {"fileid":"1234"}" 
"https://www.googleapis.com/upload/drive/v3/files?uploadType=media" 

注意我没有在 curl 中测试上传,这只是一个猜测。

【讨论】:

  • 你能分享一个例子吗?
  • 我已经分享了我拥有的示例代码。关于您的更新:您必须登录用户阅读他们的 gmail,然后上传到他们的谷歌驱动器帐户。所有这些都必须通过 google drive 和 gmail 进行身份验证。未经身份验证,您无法访问用户的私人数据。
  • 我已经创建了 credential.js 。
  • 通过身份验证后,您可以在上面的 curl 代码中使用访问令牌。如果您决定使用 php,则只需让它处理身份验证,如 php 快速入门 developers.google.com/drive/api/v3/quickstart/php 中所示
  • 请提供驱动器中未命名文件的灵魂。文件已上传,但其名称为 untitled.pdf 或 txt in google drive。
【解决方案3】:

您可以使用逻辑应用将文件从 Azure Blob 存储发送到 Google Drive 以及电子邮件附件。

https://docs.microsoft.com/en-us/azure/connectors/connectors-create-api-azureblobstorage

或者,存储在 Azure Blob 中的文件可以是具有公共 URL 的地址,前提是你在容器和/或 Blob 上设置了正确的权限。

【讨论】:

  • 请提供驱动器中未命名文件的建议。文件已上传,但其名称为 untitled.pdf 或 txt in google drive。
猜你喜欢
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 2020-03-07
  • 1970-01-01
  • 2023-03-30
相关资源
最近更新 更多