brightzone/gremlin-php

PHP的gremlin-server客户端

v3.1.1 2019-01-21 23:20 UTC

README

这是一个用于PHP的Gremlin服务器客户端。它允许您针对图数据库(包括Neo4j、Titan等)运行Gremlin查询。您可以阅读使用Tinkerpop 3和PHP开始运行文章找到入门教程。

此驱动程序目前支持TP3+。

如果您需要TP2兼容的PHP驱动程序,请查看rexpro-php

Build Status Latest Stable Version Coverage Status Total Downloads License

Join the chat at https://gitter.im/PommeVerte/gremlin-php

安装

PHP Gremlin-Server客户端

推荐方法是通过composer。

运行以下命令:

php composer.phar require brightzone/gremlin-php "3.*"

或者

"brightzone/gremlin-php": "3.*"

将以下内容添加到您的composer.json文件的require部分:

Tinkerpop 3.3.x服务器配置

此驱动程序现在支持带有基本beta序列化器的GraphSON 3.0。您可以通过以下方式使用此序列化器:

  $db = new Connection();
  $db->message->registerSerializer('\Brightzone\GremlinDriver\Serializers\Gson3', TRUE);

如果您希望继续使用稳定的GraphSON 1.0序列化器,则需要配置服务器使用GraphSON 1.0。要做到这一点,请确保将您的gremlin-server.yaml配置文件中的# application/json序列化器替换为以下内容:

- { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0, config: { ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV1d0]  }}        # application/json

升级

在主要版本更改之间引入了BC不兼容的更改。因此,如果您要从1.0升级到2.0.0,请阅读CHANGELOG

使用方法

Connection类存在于GremlinDriver命名空间中。

require_once('vendor/autoload.php');
use \Brightzone\GremlinDriver\Connection;

$db = new Connection;

功能

您可以通过阅读API获取更多信息。

基本连接

可以通过创建一个新的Connection来创建基本连接,如下所示。

$db = new Connection([
    'host' => 'localhost',
    'graph' => 'graph'
]);
//you can set $db->timeout = 0.5; if you wish
$db->open();

$result = $db->send('g.V(2)');
//do something with result
$db->close();

请注意,“graph”是gremlin-server中配置的图名称(不是遍历的引用,即g = graph.traversal()

还可以按以下方式指定认证凭据:

$db = new Connection([
    'host' => 'localhost',
    'graph' => 'graph',
    'username' => 'pomme',
    'password' => 'hardToCrack'
]);
//you can set $db->timeout = 0.5; if you wish
$db->open();
$db->send('g.V(2)');
//do something with result
$db->close();

请查看SSL部分,以获取使用TP提供的配置文件的示例。

您可以在此处找到所有可用的Connection类选项。

绑定

绑定对于几个原因很重要。它们可以防止代码注入,但还可以防止服务器在每次运行时编译脚本。

以下示例说明了这两个点

$unsafeUserValue = 2; //This could be anything submitted via form.
$db = new Connection([
    'host' => 'localhost',
    'port' => 8182,
    'graph' => 'graph',
]);
$db->open();

$db->message->bindValue('CUSTO_BINDING', $unsafeUserValue); // protects from injections
$result1 = $db->send('g.V(CUSTO_BINDING)'); // The server compiles this script and adds it to cache

$db->message->bindValue('CUSTO_BINDING', 5);
$result2 = $db->send('g.V(CUSTO_BINDING)'); // The server already has this script so gets it from cache without compiling it, but runs it with 5 instead of $unsafeUserValue
$result3 = $db->send('g.V(5)'); // The script is different so the server compiles this script and adds it to cache

//do something with result
$db->close();

如上例所示,不使用绑定可能会非常昂贵,因为服务器需要为每个新脚本进行编译。

会话

会话允许您在多个请求之间维护变量和绑定。

$db = new Connection([
    'host' => 'localhost',
    'port' => 8182,
]);
$db->open();
$db->send('cal = 5+5', 'session'); // first query sets the `cal` variable
$result = $db->send('cal', 'session'); // result = [10]
//do something with result
$db->close();

事务

事务将允许您回滚或确认跨多个请求所做的更改集。

$db = new Connection([
    'host' => 'localhost',
    'port' => 8182,
    'graph' => 'graphT',
]);
$db->open();

$db->transactionStart();

$db->send('t.addV().property("name","michael")');
$db->send('t.addV().property("name","john")');

$db->transactionStop(FALSE); //rollback changes. Set to TRUE to commit.
$db->close();

请注意,“graphT”上面指的是支持事务的图。事务会自动启动会话。您可以使用graph.features()检查您的图支持哪些功能。

还可以使用lambda表达式表示事务

$db = new Connection([
    'host' => 'localhost',
    'port' => 8182,
    'graph' => 'graphT',
]);
$db->open();

$db->transaction(function($db){
    $db->send('t.addV().property("name","michael")');
    $db->send('t.addV().property("name","john")');
}, [$db]);

$db->close();

这将提交这些更改,或者在发生错误时返回一个Exception(并自动回滚更改)。使用此语法的优点是可以处理故障重试场景。

有时实现事务查询的故障重试策略非常重要。一个例子是在同时写入相同元素时,数据库(如Titan)在元素被锁定时会抛出错误。当这种情况发生时,你很可能会想让驱动程序尝试重试查询几次,直到元素解锁并继续写入。对于这种情况,你可以这样做

$db = new Connection([
    'host' => 'localhost',
    'port' => 8182,
    'graph' => 'graphT',
    'retryAttempts' => 10
]);
$db->open();

$db->transaction(function($db){
    $db->send('t.addV().property("name","michael")');
    $db->send('t.addV().property("name","john")');
}, [$db]);

$db->close();

这将尝试运行查询10次,然后再完全失败。值得注意的是,retryAttempts也适用于-out-of-session-查询

$db->send('gremlin.code.here'); // will retry multiple times if 'retryAttempts' is set

高级功能

消息对象

有时你可能需要更细粒度地控制单个请求。原因可能包括使用自定义序列化程序、不同的查询语言(gremlin-pythongremlin-scalajava)、指定请求超时限制或本地别名。对于这些情况,你可以按如下方式构建自定义的Message对象

$message = new Message;
$message->gremlin = 'custom.V()'; // note that custom refers to the graph traversal set on the server as g (see alias bellow)
$message->op = 'eval'; // operation we want to run
$message->processor = ''; // the opProcessor the server should use
$message->setArguments([
                'language' => 'gremlin-groovy',
                'aliases' => ['custom' => 'g'],
                // ... etc
]);
$message->registerSerializer('\Brightzone\GremlinDriver\Serializers\Json');

$db = new Connection();
$db->open();
$db->send($message);
//do something with result
$db->close();

当然,你也可以通过$db->message以相同的方式影响当前数据库消息。

有关可用参数和值的完整列表,请参阅TinkerPop驱动程序的文档

SSL

当安全性很重要时,你将想要使用可用的SSL功能。你可以这样做

$db = new Connection([
    'host' => 'localhost',
    'graph' => 'graph',
    'ssl' => TRUE
]);
//you can set $db->timeout = 0.5; if you wish
$db->open();
$db->send('g.V(2)');
//do something with result
$db->close();

请注意,在php 5.6+中,你需要以与stream_context_create()相同的方式提供证书信息。在这种情况下,你的Connection()调用可能看起来像以下这样(用你自己的证书和/或包替换)

$db = new Connection([
    'host' => 'localhost',
    'graph' => 'graph',
    'ssl' => [
        "ssl"=> [
            "cafile" => "/path/to/bundle/ca-bundle.crt",
            "verify_peer"=> true,
            "verify_peer_name"=> true,
        ]
    ]
]);

如果你使用的是捆绑的gremlin-server-secure.yaml文件,你可以使用这个配置来连接到它。对于开发和测试目的,你可以使用这个配置

序列化器

序列化器可以在gremlin-server级别上更改。这允许用户设置自己的序列化规则。该库默认包含一个Json序列化器。任何实现SerializerInterface的其他序列化器都可以通过以下方式动态添加

$db = new Connection;
$serializer = $db->message->getSerializer() ; // returns an instance of the default JSON serializer
echo $serializer->getName(); // JSON
echo $serializer->getMimeType(); // application/json

$db->message->registerSerializer('namespace\to\my\CustomSerializer', TRUE); // sets this as default
$serializer = $db->message->getSerializer(); // returns an instance of the CustomSerializer serializer (default)
$serializer = $db->message->getSerializer('application/json'); // returns an instance of the JSON serializer

你可以以这种方式添加多个序列化器。当gremlin-server响应用户请求时,gremlin-php将能够使用适当的一个来反序列化消息。

API

完整的API可以在这里找到。

单元测试

需要Neo4J来完全测试套件。它默认不捆绑到gremlin-server中,因此你需要手动安装它,如下所示

bin/gremlin-server.sh -i org.apache.tinkerpop neo4j-gremlin 3.2.8

(将版本号替换为你gremlin-server的版本号)

复制以下文件

cp <gremlin-php-root-dir>/build/server/gremlin-server-php.yaml <gremlin-server-root-dir>/conf/
cp <gremlin-php-root-dir>/build/server/neo4j-empty.properties <gremlin-server-root-dir>/conf/
cp <gremlin-php-root-dir>/build/server/gremlin-php-script.groovy <gremlin-server-root-dir>/scripts/

然后,你可以按以下方式运行gremlin-server

bin/gremlin-server.sh conf/gremlin-server-php.yaml

然后通过以下方式运行单元测试

# make sure test dependecies are installed 
composer install # PHP >=5.6
composer update # PHP 5.5

# Run the tests
phpunit -c build/phpunit.xml

浏览器/tets/webtest.php文件

如果你的gremlin-php文件夹在Web路径上。你还可以加载tests/webtest.php而不是使用命令行来运行PHPUNIT测试。

这在某些WAMP或有限访问命令行情况下很有用。