2017-07-28 30 views
1

我不能獲得穩定的劇本時,我嘗試上傳的docx文件,以谷歌驅動器,然後下載文件,但爲PDF。谷歌API,用於PHP(驅動API)導出爲.PDF上傳.docx文件

代碼:

//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.

我做錯了什麼?或者我應該做一些循環,試圖下載文件,直到成功?

+0

'$文件 - > id'沒有這樣的鍵?不應該是'$ file-> data' – pokeybit

+0

'$ service-> files-> create()'返回id對象字段包含在Google雲端硬盤上創建的文件的ID。除了錯誤代碼500' $ file-> id'總是存在。 – Yurciu

+0

也許創建文件和您的導出電話之間的延遲 – pokeybit

回答

0

好的。所以,我花兩天時間尋找解決方案,我想出了幾個結論:

  1. 使用服務器到服務器的身份驗證,必須創建服務帳戶,用的是「獨立的」谷歌驅動器帳戶。這意味着如果您通過腳本創建文件,則會在服務帳戶上創建文件,並且只能通過API訪問此文件。
  2. 您可以將權限分配給創建的文件,你的真正的谷歌帳戶連接到文件,比您可以訪問通過谷歌雲端硬盤中的文件。您無法將所有權從服務帳戶轉移到Google帳戶,因爲此時Google PHP API沒有適當的方法。 或者我沒有看到設置此方法。Class summary.

  3. 關鍵是使用Exponential backoff。換句話說,除非成功才嘗試。 (͡°͜ʖ͡°)

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); 
+0

您的退避是線性的,而不是指數。 – pinoyyid