无法通过PHP Client连接Neo4j 4.1.12的问题排查求助
运行Neo4j 4.1.12版本,可通过浏览器使用登录凭证经Bolt连接成功。使用neo4j-php-client编写代码如下:
public function __construct($table = null){ $config = config('Database')->neo4j; if (!empty($config['Username'])){ $auth = Authenticate::basic($config['Username'],$config['Password']); } else { $auth = null; } $this->transact = $config['Transact']; // 配置是否启用事务功能 $this->client = ClientBuilder::create()->withDriver('bolt','bolt://neo4j:PW_THAT_WORKS@localhost:7687')->build(); $this->table = $table; } public function query($query,$params = []){ $client = $this->client; $statement = new Statement($query,$params); if ($this->transact){ $result = $client->writeTransaction(static function (TransactionInterface $tsx) use ($statement) { return $tsx->runStatement($statement); }); } else { $result = $client->runStatement($statement); } return $result; } public function insert($data = null, bool $returnID = true){ if (empty($this->table)){ return false; } $result = $this->query('CREATE ('.$this->table. ')'); print'<pre>';print_r($result);print'</pre>'; }
调用以下代码时:
$neo4j = new \App\Models\Neo4jModel('n:Test'); $neo4j->insert(array('Hello'=>'World','Foobar'=>'Baz'));
出现连接错误:Cannot connect to any server on alias: bolt with Uris: ('bolt://neo4j:PW_THAT_WORKS@localhost:7687')。
但在Neo4j命令行执行CREATE (n:Test)可正常完成,返回Added 1 label, created 1 node, completed after 408 ms.。尝试改用HTTP驱动时,抛出Http\Discovery\Exception\DiscoveryFailedException异常。通过curl访问localhost:7474可正常获取服务信息:
curl localhost:7474 { "bolt_routing" : "neo4j://localhost:7687", "transaction" : "http://localhost:7474/db/{databaseName}/tx", "bolt_direct" : "bolt://localhost:7687", "neo4j_version" : "4.1.12", "neo4j_edition" : "community" }
1. Bolt连接认证方式错误
代码中已构建$auth认证对象,但创建Client时未传入,而是直接在URI内嵌用户名密码。Neo4j 4.x版本配合neo4j-php-client时,推荐通过withDriver的第三个参数传入认证对象,而非URI内嵌。
修改Client初始化代码:
$this->client = ClientBuilder::create() ->withDriver('bolt', 'bolt://localhost:7687', $auth) ->build();
2. HTTP驱动依赖缺失
Http\Discovery\Exception\DiscoveryFailedException异常通常是因为缺少PHP HTTP客户端适配器。执行以下命令安装所需依赖:
composer require php-http/guzzle6-adapter
3. 未使用传入的节点属性数据
insert方法接收了$data参数,但实际执行的Cypher语句未使用该参数,导致创建节点时无法设置属性。同时应使用参数化查询避免注入风险,修改insert方法:
public function insert($data = null, bool $returnID = true){ if (empty($this->table) || empty($data)){ return false; } // 拆分变量名与标签,处理传入的'n:Test'格式 preg_match('/^(\w+):(\w+)$/', $this->table, $matches); $varName = $matches[1] ?? 'n'; $label = $matches[2] ?? ''; if (empty($label)) return false; // 构造参数化Cypher语句 $query = "CREATE ($varName:$label) SET $varName = \$data"; if ($returnID) { $query .= " RETURN ID($varName) as nodeId"; } $result = $this->query($query, ['data' => $data]); print'<pre>';print_r($result);print'</pre>'; }
4. 检查PHP环境的Bolt依赖扩展
neo4j-php-client的Bolt驱动依赖ext-sockets扩展。通过php -m命令查看是否已安装,若未安装,需在php.ini中添加extension=sockets并重启PHP服务。
内容的提问来源于stack exchange,提问作者Antony

