It is totally feasible and user-friendly in Neoxygen's NeoClient.
The first thing to make sure, is that you activate the response formatter :
$client = ClientBuilder::create()
->setAutoFormatResponse(true)
->addConnection(xxx...)
->build();
Secondly, concerning your query I would definitely set a depth limit to avoid memory behaviors depending of your graph connectedness :
MATCH (a:`Category`{category_id:0})-[r:HAS_CHILD*..20]->(b:`Category`)
RETURN b,r
Then, you can send it with the client and benefit that the client will remap the results in a graph structure :
$query = 'MATCH (a:`Category`{category_id:{id}})-[r:HAS_CHILD*..20]->(b:`Category`)'
RETURN b,r';
$children = $client->sendCypherQuery($q, ['id'=>0])->getResult()->getNodes();
Now, each node will know what he has as relationships and relationships know their start and end nodes, example :
$children
are nodes in the first depth, so
$rels = $children->getOutboundRelationships();
$nodes = [];
foreach ($rels as $rel) {
$nodes[] = $rel->getEndNode();
}
$nodes holds now all the nodes in depth 2.
There is, currently, no method to get directly the connected nodes from a node object without getting first the relationship, maybe something I can add to the client.