Я использую Google PHP API Client v2.0 в приложении, которое я запускаю в Google App Engine на локальном хосте. Когда я публикую свое приложение в рабочей среде Google App Engine, я не получаю сообщения об ошибке, но она возникает периодически, поэтому трудно понять, повезло ли мне просто в рабочей среде.
Мой клиент API Google пытается записать файл на мой Google Диск. Этот код работал хорошо в течение нескольких месяцев, но сегодня утром он внезапно перестал работать. Я проверил статус Google API, и они не сообщают о каких-либо сбоях. Когда я выполняю любой из вызовов API, я получаю этот расплывчатый ответ об ошибке:
Неустранимая ошибка: fopen(): неверный ответ от сервера API. в /Users/me/googleappengine/stuff-otherstuff-111111/vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php в строке 312
Файл действительно создается на Google Диске, поэтому мой вызов API проходит, но любой ответ, возвращаемый моему сценарию, вызывает фатальный сбой.
На несколько минут снова заработало, теперь опять зависает. Я нигде не могу найти решения ошибки Invalid response from API server... и она появляется периодически. Похоже, это не связано с моим кодом, но Google говорит, что у него нет никаких сбоев.
Что мне не хватает? Как я могу это исправить?
<?php
include_once('code-base.php');
require_once('vendor/autoload.php');
$client = new Google_Client();
$client->setApplicationName(getSetting('APP_NAME'));
$client->setAuthConfig(json_decode(getSetting('localhost_google_client_secret'), true));
$client->setAccessType("offline");
$client->setScopes(array(Google_Service_Drive::DRIVE));
$client->setHttpClient(new GuzzleHttp\Client(['verify'=>'ca-bundle.crt']));
$accesstoken = json_decode(getSetting('localhost_google_oauth_token'), true);
$client->setAccessToken($accesstoken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
print "access token is expired\n";
$refreshtoken = getSetting('localhost_google_refresh_token');
print "refresh token: $refreshtoken\n";
$client->refreshToken($refreshtoken);
$newtokenjson = json_encode($client->getAccessToken());
print "new token: $newtokenjson\n";
printf("before: %s\n\nafter: %s\n\n", $accessToken, $newtokenjson);
//file_put_contents($credentialsPath, $newtokenjson);
updateSetting('localhost_google_oauth_token', $newtokenjson);
}
print "after checking access token expired\n";
print "before drive service\n";
$driveservice = new Google_Service_Drive($client);
print "after drive service\n";
$parentfolderid = getSetting('GDRIVE_EXPORT_DUMP');
$title = "00005 test gdrive.csv";
$filetype = 'text/csv';
$contents = "The quick brown fox jumped over the lazy dog.";
$file = new Google_Service_Drive_DriveFile();
$file->setName($title);
$file->setDescription($title);
$file->setMimeType($filetype);
$file->setParents(array($parentfolderid));
try {
if ($contents == null) {
print "contents of file are null, creating empty file\n";
$createdFile = $driveservice->files->create($file);
print "after creating empty file\n";
} else {
$contentsarray = array('data' => $contents, 'mimeType' => $filetype, 'uploadType' => 'media');
if ($options != null) {
foreach($options as $key => $value) {
$contentsarray[$key] = $value;
}
}
print "file contents: ".var_export($contentsarray, true)."\n";
$createdFile = $driveservice->files->create($file, $contentsarray);
print "after create file with contents\n";
}
return $createdFile;
} catch (Exception $e) {
print "EXCEPTION: An error occurred: " . $e->getMessage()."\n";
}
РЕДАКТИРОВАТЬ: мой код, похоже, теперь постоянно терпит неудачу с сообщением Invalid response from API server. Он дает сбой только в том месте, где код взаимодействует с Google. Эти два места — когда я звоню refreshToken() (что случается редко), а другое — когда я звоню create().
Мой друг запускал этот точный код на своей машине с той же настройкой (насколько мы можем судить... тот же код, те же библиотеки, тот же токен oauth и т. д.), и это работает для него.
Примечания: функция getSetting() в приведенном выше коде просто извлекает некоторые строки из моей базы данных, которые я использую для целей настройки. Кроме того, вызов setHttpClient() необходим, потому что он работает внутри Google App Engine, который работает на PHP 5.5, который имеет испорченный пакет CA, и мне требуется предоставить правильный.
Что может быть причиной того, что он не работает для меня каждый раз, но работает для моего друга?
fopenв кодеStreamHandler, я подозреваю, что ошибка возникает либо при создании, либо при чтении файла с Диска. Пожалуйста, предоставьте минимальный пример кода, который может воспроизвести эту ошибку, и мы будем рады изучить ее. - person Nicholas   schedule 19.12.2016$contentsarray, может быть какой-то текстовый формат или специальные символы, которые не разрешены для создания файла. Вы можете попробоватьprint_r($contentsarray)внутри своегоcatch block- person Aabir Hussain   schedule 27.12.2016