Tree Connector problem


#1

Getting a PHP Fata error: Uncaught Error: Maximum function nesting level of ‘256’ reached, aborting! in …/db_common.php:88

Using this code:

$res = new PDO($dsn, $user, $db_pwd);
$tree_conn = new TreeConnector($res,“PDO”);
$tree_conn->render_sql($strSelect, ‘id’, ‘name’, ‘’, ‘parent’);

I have recently moved to PHP 7.4 from 5.6, and converted to PDO. It was working OK in 5.6.
The hierarchical table from which the SELECT statement derives its data has id, name and parent columns.
Using $tree_conn->render_table gives the same error.
The table is not large (64 rows) and the tree depth is only around 6 or 7.


#2

I’d guess there’s a difference between your php.ini settings from 5.6 to 7.4. See this answer on stackexchange for some info.


#3

Yes - I guess so, but that can’t be the whole picture, because when I disable xdebug (which has the effect of removing the nesting limit) I get a memory limit error instead.
There must be some difference in the way the tree connector handles recursion when deployed with PDO.
The problem arises in strategy.php - specifically the render_set() function:

public function render_set($res, $name, $dload, $sep, $config, $mix){
	$output="";
	$index=0;
	$conn = $this->conn;
    $config_copy = new DataConfig($config);
	$this->mix($config, $mix);
	while ($data=$conn->sql->get_next($res)){
		$data = $this->simple_mix($mix, $data);
		$data = new $name($data,$config,$index);
		$conn->event->trigger("beforeRender",$data);
		//there is no info about child elements,
		//if we are using dyn. loading - assume that it has,
		//in normal mode juse exec sub-render routine
		if ($data->has_kids()===-1 && $dload)
				$data->set_kids(true);
		$output.=$data->to_xml_start();
		if ($data->has_kids()===-1 || ( $data->has_kids()==true && !$dload)){
			$sub_request = new DataRequestConfig($conn->get_request());
            //$sub_request->set_fieldset(implode(",",$config_copy->db_names_list($conn->sql)));
			$sub_request->set_relation($data->get_id());
			$output.=$this->render_set($conn->sql->select($sub_request), $name, $dload, $sep, $config_copy, $mix);
		}
		$output.=$data->to_xml_end();
		$index++;
	}
	$this->unmix($config, $mix);
	return $output;
}

I’m guessing that somehow the recursion, (which should stop when the node has no child nodes) continues regardless. This snippet from the Samples on git hub suggests that it is necessary to add some code to check for child nodes:

function child_setter($data){
//the check is kind of lame, in real table you most probably may have some more stable way to detect is item have childs or not
if ($data->get_value(“taskId”)%100>1)
$data->set_kids(false);
else
$data->set_kids(true);
}
require("…/…/codebase/tree_connector.php");
$tree = new TreeConnector($res, “PDO”);
//
$tree->event->attach(“beforeRender”,“child_setter”);
$tree->render_table(“tasks”,“taskId”,“taskName”,"",“parentId”);


#4

Fixed it - the problem was caused by having the ROOT node with an ID of Zero.
I wrote a code snippet to adjust all the IDs up by one, and the Connector works fine.
Good to know that it was a simple fix in the end…

In future, I will ensure that any hierarchical tables never have a zero ID value.