使用PHP保存到本地Google数据存储区

时间:2013-11-16 21:45:00

标签: php google-app-engine google-cloud-datastore

以下代码将实体插入远程Google数据存储区:

require_once('google-api-php-client/src/Google_Client.php');
require_once('google-api-php-client/src/contrib/Google_DatastoreService.php');

$client = new Google_Client();
$client -> setApplicationName("myApp");

$serviceAccount = 'myServiceAccount@developer.gserviceaccount.com';
$key = file_get_contents('super/secret/encryptedKey-privatekey.p12');

$client -> setAssertionCredentials(new Google_AssertionCredentials(
                          $serviceAccount, 
                          array('https://www.googleapis.com/auth/userinfo.email',
                          'https://www.googleapis.com/auth/datastore'), $key));

$datastore = new Google_DatastoreService($client);

$path = new Google_KeyPathElement();
$path -> setName('testName');
$path -> setKind('testKind');

$key = new Google_Key();
$key -> setPath(array($path));

$entities = new Google_Entity();
$entities -> setKey($key);

$mutation = new Google_Mutation();
$mutation -> setInsert(array($entities));

$blindWrite = new Google_BlindWriteRequest();
$blindWrite -> setMutation($mutation);

$datastore -> datasets -> blindWrite('myApp', $blindWrite);

现在这不适合本地开发,所以我更改了'basePath'中的google-api-php-client/src/config.php

'basePath' => 'https://www.googleapis.com',

'basePath' => 'http://localhost:53290',

根据应用启动器日志,我的API服务器。

不幸的是,这不起作用,对本地API服务器的任何请求都会导致以下错误:

Fatal error: Uncaught exception 'Google_ServiceException' with message 'Error calling POST http://localhost:53290/datastore/v1beta1/datasets/myApp/blindWrite: (400) HTTP requires CRLF terminators' in ***\google-api-php-client\src\io\Google_REST.php:66

但是,访问http://localhost:53290有效并返回:     {app_id:dev~myApp,rtok:'0'}

有人知道造成这个错误的原因是什么吗?请求完全相同,我知道本地数据存储区正在使用其他语言。

3 个答案:

答案 0 :(得分:3)

警告:我还没有在GAE上用PHP开发,只在python和java中开发。

根据this answer,PHP运行时当前无法访问GAE数据存储区;相反,它使用Google Cloud Datastore,访问方式不同。 (只是想澄清一下,因为你用gae-datastore标记了你的问题)

AFIAK,GAE开发服务器不支持Google Cloud Datastore(您通过Google_DatastoreService.php使用)。要在本地模拟Google Cloud Datastore,您需要运行Google Cloud Datastore development server。 - 但是,如果你甚至可以使用它取决于PHP客户端是使用他们的protocal缓冲区还是他们的JSON API。只支持前者。请参阅该页面上的注释。所以你可能会陷入困境。

假设您可以使用本地devserver:

我不知道google-api-php / client / src / config.php中指的是什么basepath,如果在运行Google Cloud Datastore本地devserver时更改它是一种方法。 docs for the devserver表示您应该修改环境变量DATASTORE_HOST和DATASTORE_DATASET。

(顺便说一句:我相信您的应用启动器日志中的API服务器条目是指与您的问题无关的Google Cloud Endpoints。)

答案 1 :(得分:3)

如果有人想使用不同的Cloud Datastore进行开发和生产,这是最简单的解决方法:

创建两个应用程序:

  • 对myApp
  • 对myApp-dev的

为两个应用程序激活数据存储区API。我有点惊讶,但只要您拥有正确的service-account-id和私钥,您就可以从任何应用程序访问数据存储区。

实施一个简单的开关:

const DATASTORE_APP_NAME_PRODUCTION = 'myApp';
const DATASTORE_SERVICE_ACCOUNT_NAME_PRODUCTION = 
'production-service-account-id@developer.gserviceaccount.com';

const DATASTORE_APP_NAME_DEVELOPMENT = 'myApp-dev';
const DATASTORE_SERVICE_ACCOUNT_NAME_DEVELOPMENT = 
'dev-service-account-id@developer.gserviceaccount.com';

if (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 
'Google App Engine') !== false) {
    $runMode = 'PRODUCTION';
} else {
    $runMode = 'DEVELOPMENT';
}

如果要在应用程序中访问Cloud Datastore,请执行以下操作:

$serviceAccount = constant('DATASTORE_SERVICE_ACCOUNT_NAME_'.$runMode);
$appName = constant('DATASTORE_APP_NAME_'.$runMode);
$key = file_get_contents('secret/path/'.$runMode.'-privatekey.p12');

$client -> setAssertionCredentials(
new Google_AssertionCredentials($serviceAccount,
array('https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/datastore'), $key));

答案 2 :(得分:2)

我最近创建了一个可以处理此问题的库:https://github.com/pwhelan/datachore。真正的魔力在于:https://github.com/pwhelan/datachore/blob/master/src/Datastore/GoogleRemoteApi.php

部署后,代码也能正常工作。