ostico / phporient
PHPOrient 是基于 OrientDB 二进制协议的一个优秀的 PHP 驱动程序。
Requires
- php: >=5.4.0
- psr/log: ~1.0
Requires (Dev)
- monolog/monolog: 1.11.*
- ostico/phpdoc-md: dev-master
- phpdocumentor/phpdocumentor: dev-master
- phpdocumentor/template-zend: 1.3.0
- phpunit/phpunit: 4.4
- satooshi/php-coveralls: ~1.0
README
PHPOrient 是基于 OrientDB 二进制协议的 PHP 驱动程序。
状态:稳定 请报告任何您发现的错误,以便我们能够为所有人改进库。
要求
- PHP 版本 >= 5.4 (启用 Socket 扩展)
- Orientdb 版本 1.7.4 或更高。
PhpOrient 适用于 32位和 64位平台。
注意,如果您使用 32位平台,您必须在您的应用程序中使用以下库之一以避免 Java 长整数丢失重要的数字。此外,应将这些 php 模块加载到系统中以实现更好的驱动程序性能。
- BCMath 高精度数学(更快,推荐)
- GNU 多精度
由于 PHP 的平台依赖性,在 PhpOrient 中,出于设计考虑,数字总是被当作字符串处理。在 32位平台上,数字必须被当作字符串处理,因为大于 2^32 的值将会丢失,并且必须使用 BCMath/GMP 模块来避免这种情况。为了使所有平台(32位和 64位)的结果一致,并让用户/开发者决定如何使用自己的数据(通过手动转换),所有数值数据类型都使用字符串。
安装
PhpOrient 的主要公共仓库托管在 https://github.com/Ostico/PhpOrient.git。
要安装库的最新版本,只需输入
git clone https://github.com/Ostico/PhpOrient.git
您希望其文件所在的位置。
如果您尚未全局安装,您必须下载 composer。只需在 PhpOrient 目录中运行此命令。
php -r "readfile('https://getcomposer.org.cn/installer');" | php
现在获取与 PhpOrient 一起工作的必需库
php composer.phar --no-dev install
注意
如果您已经安装了 composer 或您的现有项目使用它,您可以通过 Composer https://packagist.org.cn/packages/ostico/phporient 安装/添加 PhpOrient,它与 GitHub 仓库链接(因此始终是最新的),并将其作为依赖项添加到您的项目中。
php composer.phar require "ostico/phporient:dev-master" --update-no-dev
贡献
- 复制项目。
- 进行您的更改。
- 为它添加测试。这很重要,这样我就不会无意中在未来版本中破坏它。
- 向我发送拉取请求(将拒绝向 master 发送的拉取请求)
- ???
- 盈利
如何运行测试
- 使用
php composer.phar install
- 通过从项目目录中运行 ./ci/ci-start.sh 来启动 Orient,它将下载最新的 Orient 并对配置和数据库进行一些更改以进行测试
- 运行:./vendor/bin/phpunit
用法
PhpOrient 指定自动加载信息,Composer 生成一个 vendor/autoload.php 文件。您可以简单地包含此文件,并免费获得自动加载,并使用完全限定名称声明 PhpOrient 客户端的用法。
require "vendor/autoload.php"; use PhpOrient\PhpOrient;
完整的 phpdoc 参考信息可以在ApiIndex或PhpOrient Wiki中找到
客户端初始化
有几种初始化客户端的方法
$client = new PhpOrient( 'localhost', 2424 ); $client->username = 'root'; $client->password = 'root_pass';
$client = new PhpOrient(); $client->hostname = 'localhost'; $client->port = 2424; $client->username = 'root'; $client->password = 'root_pass';
$client = new PhpOrient(); $client->configure( array( 'username' => 'root', 'password' => 'root_pass', 'hostname' => 'localhost', 'port' => 2424, ) );
连接以执行服务器管理操作
$client = new PhpOrient( 'localhost', 2424 ); $client->username = 'root'; $client->password = 'root_pass'; $client->connect();
$client = new PhpOrient( 'localhost', 2424 ); $client->connect( 'root', 'root_pass' );
数据库创建
$new_cluster_id = $client->dbCreate( 'my_new_database', PhpOrient::STORAGE_TYPE_MEMORY, # optional, default: STORAGE_TYPE_PLOCAL PhpOrient::DATABASE_TYPE_GRAPH # optional, default: DATABASE_TYPE_GRAPH );
删除数据库
$client->dbDrop( $this->db_name, PhpOrient::STORAGE_TYPE_MEMORY # optional, default: STORAGE_TYPE_PLOCAL );
检查数据库是否存在
$client->dbExists( 'my_database', PhpOrient::DATABASE_TYPE_GRAPH # optional, default: DATABASE_TYPE_GRAPH );
获取数据库列表
$client->dbList();
打开数据库
$ClusterMap = $client->dbOpen( 'GratefulDeadConcerts', 'admin', 'admin' );
发送命令
仅用于在数据库上执行非幂等命令
$client->command( 'create class Animal extends V' ); $client->command( "insert into Animal set name = 'rat', specie = 'rodent'" );
执行查询
$client->query( 'select from followed_by limit 10' );
执行异步查询(回调)
$myFunction = function( Record $record) { var_dump( $record ); }; $client->queryAsync( 'select from followed_by', [ 'fetch_plan' => '*:1', '_callback' => $myFunction ] );
加载记录
$record = $client->recordLoad( new ID( '#3:0' ) )[0]; $record = $client->recordLoad( new ID( 3, 0 ) )[0]; $record = $client->recordLoad( new ID( [ 'cluster' => 3, 'position' => 0 ] ) )[0];
创建记录
$recordContent = [ 'accommodation' => 'houses', 'work' => 'bazar', 'holiday' => 'sea' ]; $rec = ( new Record() )->setOData( $recordContent )->setRid( new ID( 9 /* set only the cluster ID */ ) ); $record = $this->client->recordCreate( $rec );
更新记录
要更新记录必须有一个。
如果没有记录,可以指定RID和数据创建一个新记录
$_recUp = [ 'accommodation' => 'hotel', 'work' => 'office', 'holiday' => 'mountain' ]; $recUp = ( new Record() )->setOData( $_recUp )->setOClass( 'V' )->setRid( new ID( 9, 0 ) ); $updated = $client->recordUpdate( $recUp );
否则,可以处理之前加载/创建的记录
/* Create/Load or Query for a Record */ $recordContent = [ 'accommodation' => 'houses', 'work' => 'bazar', 'holiday' => 'sea' ]; $rec = ( new Record() )->setOData( $recordContent )->setRid( new ID( 9 ) ); $record = $client->recordCreate( $rec ); /* or Query for an existent one */ $record = $client->query( "select from V where @rid = '#9:0'" )[0]; /* NOW UPDATE */ $_recUp = [ 'accommodation' => 'bridge', 'work' => 'none', 'holiday' => 'what??' ]; $recUp = $record->setOData( $_recUp ); $updated = $client->recordUpdate( $recUp );
通过节点深度导航加载记录(回调)
$myFunction = function( Record $record) { var_dump( $record ); }; $client->recordLoad( new ID( "9", "1" ), [ 'fetch_plan' => '*:2', '_callback' => $myFunction ] );
删除记录
$delete = $client->recordDelete( new ID( 11, 1 ) );
执行OrientDB SQL批处理
$cmd = 'begin;' . 'let a = create vertex set script = true;' . 'let b = select from v limit 1;' . 'let e = create edge from $a to $b;' . 'commit retry 100;'; $lastRecord = $client->sqlBatch( $cmd );
事务
// create some record stuffs $rec2Create = [ 'oClass' => 'V', 'oData' => [ 'alloggio' => 'albergo' ] ]; $rec = Record::fromConfig( $rec2Create ); $first_rec = $client->recordCreate( $rec ); $rec3Create = [ 'oClass' => 'V', 'oData' => [ 'alloggio' => 'house' ] ]; $rec = Record::fromConfig( $rec3Create ); $sec_rec = $client->recordCreate(); //get the transaction and start it $tx = $client->getTransactionStatement(); //BEGIN THE TRANSACTION $tx = $tx->begin(); //IN TRANSACTION $recUp = [ 'accommodation' => 'mountain cabin' ]; $rec2 = new Record(); $rec2->setOData( $recUp ); $rec2->setOClass( 'V' ); $rec2->setRid( $first_rec->getRid() ); $rec2->setVersion( $first_rec->getVersion() ); $updateCommand = $client->recordUpdate( $rec2 ); $createCommand = $client->recordCreate( ( new Record() ) ->setOData( [ 'accommodation' => 'bungalow' ] ) ->setOClass( 'V' ) ->setRid( new ID( 9 ) ) ); $deleteCommand = $client->recordDelete( $sec_rec->getRid() ); //Attach to the transaction statement, they will be executed in the same order $tx->attach( $updateCommand ); // first $tx->attach( $createCommand ); // second $tx->attach( $deleteCommand ); // third $result = $tx->commit(); /** * @var Record $record */ foreach ( $result as $record ){ if( $record->getRid() == $first_rec->getRid() ){ $this->assertEquals( $record->getOData(), [ 'accommodation' => 'mountain cabin' ] ); $this->assertEquals( $record->getOClass(), $first_rec->getOClass() ); } else { $this->assertEquals( $record->getOData(), [ 'accommodation' => 'bungalow' ] ); $this->assertEquals( $record->getOClass(), 'V' ); } } //check for deleted record $deleted = $client->recordLoad( $sec_rec->getRid() ); $this->assertEmpty( $deleted );
获取数据库大小(需要打开数据库)
$client->dbSize();
获取簇的记录ID范围
$data = $client->dataClusterDataRange( 9 );
获取一个或多个簇中的记录数
$client->dataClusterCount( $client->getTransport()->getClusterMap()->getIdList() );
获取打开数据库中的记录数
$result = $client->dbCountRecords();
重新加载数据库信息
此方法会自动更新客户端簇映射。可以在创建类或添加/删除数据簇之后使用。
$reloaded_list = $client->dbReload(); # $reloaded_list === $client->getTransport()->getClusterMap()
创建新的数据簇
$client->dataClusterAdd( 'new_cluster', PhpOrient::CLUSTER_TYPE_MEMORY # optional, default: PhpOrient::CLUSTER_TYPE_PHYSICAL );
删除数据簇
$client->dataClusterDrop( 11 );
持久连接(会话令牌)
从版本27开始,引入了一个扩展,允许使用基于令牌的会话。此功能必须在服务器配置中启用。
- 在第一次协商中,客户端可以使用
PhpOrient::setSessionToken
方法请求基于令牌的认证。 - 服务器将回复一个令牌或一个空字符串,表示它不支持基于令牌的会话并使用旧式会话。
- 对于每个请求,客户端将发送令牌,如果令牌生命周期结束,它将最终获得一个新的令牌。
在使用基于令牌的认证时,连接可以在同一服务器的用户之间共享。
$client = new PhpOrient( 'localhost', 2424 ); $client->setSessionToken( true ); // set true to enable the token based authentication $clusterID = $client->dbOpen( "GratefulDeadConcerts", 'admin', 'admin' ); $sessionToken = $client->getSessionToken(); // store this token somewhere //destroy the old client, equals to another user/socket/ip ecc. unset($client); // create a new client $client = new PhpOrient( 'localhost', 2424 ); // set the previous obtained token to re-attach to the old session $client->setSessionToken( $sessionToken ); //now the dbOpen is not needed to perform database operations $records = $client->query( 'select * from V limit 10' ); //set the flag again to true if you want to renew the token $client->setSessionToken( true ); // set true $clusterID = $client->dbOpen( "GratefulDeadConcerts", 'admin', 'admin' ); $new_sessionToken = $client->getSessionToken(); $this->assertNotEquals( $sessionToken, $new_sessionToken );
图形示例
require "vendor/autoload.php"; use PhpOrient\PhpOrient; $client = new PhpOrient(); $client->configure( array( 'username' => 'admin', 'password' => 'admin', 'hostname' => 'localhost', 'port' => 2424, ) ); $client->connect(); $client->dbCreate( 'animals', PhpOrient::STORAGE_TYPE_MEMORY ); $client->dbOpen( 'animals', 'admin', 'admin' ); $client->command( 'create class Animal extends V' ); $client->command( "insert into Animal set name = 'rat', specie = 'rodent'" ); $animal = $client->query( "select * from Animal" ); $client->command( 'create class Food extends V' ); $client->command( "insert into Food set name = 'pea', color = 'green'" ); $client->command( 'create class Eat extends E' ); $client->command( "create edge Eat from ( select from Animal where name = 'rat' ) to ( select from Food where name = 'pea' )" ); $pea_eaters = $client->query( "select expand( in( Eat )) from Food where name = 'pea'" ); $animal_foods = $client->query( "select expand( out( Eat )) from Animal" ); foreach ( $animal_foods as $food ) { $animal = $client->query( "select name from ( select expand( in('Eat') ) from Food where name = 'pea' )" )[0]; $this->assertEquals( 'pea', $food[ 'name' ] ); $this->assertEquals( 'green', $food[ 'color' ] ); $this->assertEquals( 'rat', $animal[ 'name' ] ); }
许可
Apache License, Version 2.0,请参阅LICENSE.md。