以下代码将实体插入远程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'}
有人知道造成这个错误的原因是什么吗?请求完全相同,我知道本地数据存储区正在使用其他语言。
答案 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进行开发和生产,这是最简单的解决方法:
创建两个应用程序:
为两个应用程序激活数据存储区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。
部署后,代码也能正常工作。