Google Api for PHP(Drive API)导出为.pdf上传的.docx文件

时间:2017-07-28 13:42:54

标签: php rest google-api google-drive-api google-client

当我尝试将docx文件上传到Google云端硬盘,然后以PDF格式下载该文件时,我无法获得稳定的脚本。

代码:

//Google API
require_once('vendor/autoload.php');

putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/2ab4ece19bd5.json');
$client = new Google_Client();
$client->setApplicationName('sp-gen');
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
$client->useApplicationDefaultCredentials();
$service = new Google_Service_Drive($client);

$fileMetadata = new Google_Service_Drive_DriveFile(array(
  'name' => '281e2399740c88957143507721bd0f25.docx',
  'mimeType' => 'application/vnd.google-apps.document'
  ));

$content = file_get_contents('281e2399740c88957143507721bd0f25.docx');

$file = $service->files->create($fileMetadata, array(
  'data' => $content,
  'mimeType' => 'application/vnd.google-apps.document',
  'uploadType' => 'multipart',
  'fields' => 'id')
);

$content = $service->files->export($file->id, 'application/pdf', array( 'alt' => 'media' ));
file_put_contents(str_replace('.docx', '.pdf', '281e2399740c88957143507721bd0f25.docx'), $content->getBody()->getContents());

此代码适用于20-30%的用途。有时, $ service-> files-> export()会返回错误代码500,但在许多情况下请求返回正常响应(200)但内容长度为0。

我做错了吗?或者我应该做某种循环,尝试下载文件直到成功?

1 个答案:

答案 0 :(得分:1)

行。所以我花了两天时间寻找解决方案,我得出了几个结论:

  1. 使用服务器到服务器身份验证,您必须使用“独立”的Google云端硬盘帐户创建服务帐户。这意味着如果您通过脚本创建文件,则会在服务帐户上创建文件,并且您只能通过API访问此文件。
  2. 您可以为创建的文件分配权限,将您的真实Google帐户连接到文件,也可以通过Google云端硬盘访问该文件。您无法将所有权转移到从服务帐户到Google帐户的文件,因为此时Google PHP API没有正确的方法。 或者我没有办法设置此功能。 Class summary.

  3. 关键是使用Exponential backoff。换句话说,尝试除非成功。 (͡°͜ʖ͡°)

  4. CODE:

    //Google API
    require_once('vendor/autoload.php');
    
    putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/2ab4ece19bd5.json');
    $client = new Google_Client();
    $client->setApplicationName('sp-gen');
    $client->setScopes(array('https://www.googleapis.com/auth/drive'));
    $client->useApplicationDefaultCredentials();
    $service = new Google_Service_Drive($client);
    
    $fileMetadata = new Google_Service_Drive_DriveFile(array(
      'name' => '281e2399740c88957143507721bd0f25.docx',
      'mimeType' => 'application/vnd.google-apps.document'
      ));
    
    $content = file_get_contents('281e2399740c88957143507721bd0f25.docx');
    
    $file = $service->files->create($fileMetadata, array(
      'data' => $content,
      'uploadType' => 'multipart'
    );
    
    //Create new permission
    $newPermission = new Google_Service_Drive_Permission();
    
    //set email of account, that will have access to file.
    $newPermission->setEmailAddress('<email here>');
    
    //Must be user or group, if you pass email adress
    // user | group | domain | anyone
    $newPermission->setType('user');
    
    //Could be owner but I can not set transferOwnership 
    // organizer | owner | reader | writer
    $newPermission->setRole('writer');
    
    $service->permissions->create($file->getId(), $newPermission);
    
    $file_name = str_replace('.docx', '.pdf', '281e2399740c88957143507721bd0f25.docx');
    
    $attempt = 1;
    do{
      //Wait 5000ms
      usleep(500000*$attempt);
    
      //Try to get pdf file.
      $content = $service->files->export($file->getId(), 'application/pdf', array( 'alt' => 'media' ));
    
      //Save just fetched data.
      file_put_contents($file_name, $content->getBody()->getContents());
    
      if(filesize($file_name)) break;
      else $attempt++;
    
    }while(true);