Function Doesn't Return Entire Array

I’m trying to make a page that displays the lineage of a particular individual.

Database:
In my database, each individual has a unique ID # (primary key) and the fields p1 and p2 (parent1 and parent2). P1 and p2 contain the ID #s of the individual’s parents. If p1 or p2 equals 0, then that means that particular individual has no parents.

Here is the code I’ve made using recursive functions. The escape clause with the recursive functions: if p1 or p2 = 0 (no parent), then the function is exited and the array $array is returned.


// p1() is for looping through all possible p1s in all generations
function p1($id,$cnt,$array) {
	$cnt = $cnt + 1;
	$sql = "SELECT p1 FROM adoptables WHERE a_id=$id";
	$query = mysql_query($sql);
	$row = mysql_fetch_object($query);
	$p1 = htmlspecialchars($row->p1);
	if ($p1 != 0) {
		$array[$cnt][] = $p1;
        // the array is printed so we can see it populated correctly
		print_r($array);
		echo "<b>$p1 ($cnt)<br></b>";
		p1($p1,$cnt,$array);
		p2($p1,$cnt,$array);
	}
	return $array;
}

// p2() is for looping through all possible p2s in all generations
function p2($id,$cnt,$array) {
	$cnt = $cnt + 1;
	$sql = "SELECT p2 FROM adoptables WHERE a_id=$id";
	$query = mysql_query($sql);
	$row = mysql_fetch_object($query);
	$p2 = htmlspecialchars($row->p2);
	if ($p2 != 0) {
		$array[$cnt][] = $p2;
        // the array is printed so we can see it populated correctly
		print_r($array);
		echo "<b>$p2 ($cnt)<br></b>";
		p1($p2,$cnt,$array);
		p2($p2,$cnt,$array);
	}
	return $array;
}

// $aid is derived from the page address (aka lineage.php?aid=1)
// secure_input() is a function for sanitizing user input
$aid = secure_input($_GET['aid']);


$data = p1($aid,-1,$data);
$data = p2($aid,-1,$data);

echo "<br><br>";

// this is to ensure an array is returned
print ("...".$data."...");

echo "<br><br>";

// echoes the returned array
print_r($data);

With the print_r function, I can see that everything inside the function is happening as it is supposed to. The ID # of each progressive individual is appropriately assigned to it’s section of the $array. The $cnt represents each level of the family tree: 0 = parents, 1 = grandparents, 2 = great grandparents and so on.

Here is what the result from inside the function looks like. I echoed the ID # and the level of the family three ( ID# (lvl#) ) after each iteration of the function and you can see it populates the array correctly.

Array ( [0] => Array ( [0] => 2 ) ) 2 (0)
Array ( [0] => Array ( [0] => 2 ) [1] => Array ( [0] => 4 ) ) 4 (1)
Array ( [0] => Array ( [0] => 2 ) [1] => Array ( [0] => 4 ) [2] => Array ( [0] => 11 ) ) 11 (2)
Array ( [0] => Array ( [0] => 2 ) [1] => Array ( [0] => 4 ) [2] => Array ( [0] => 12 ) ) 12 (2)
Array ( [0] => Array ( [0] => 2 ) [1] => Array ( [0] => 5 ) ) 5 (1)
Array ( [0] => Array ( [0] => 2 ) [1] => Array ( [0] => 5 ) [2] => Array ( [0] => 13 ) ) 13 (2)
Array ( [0] => Array ( [0] => 2 ) [1] => Array ( [0] => 5 ) [2] => Array ( [0] => 14 ) ) 14 (2)
Array ( [0] => Array ( [0] => 2 [1] => 3 ) ) 3 (0)
Array ( [0] => Array ( [0] => 2 [1] => 3 ) [1] => Array ( [0] => 7 ) ) 7 (1)
Array ( [0] => Array ( [0] => 2 [1] => 3 ) [1] => Array ( [0] => 7 ) [2] => Array ( [0] => 15 ) ) 15 (2)
Array ( [0] => Array ( [0] => 2 [1] => 3 ) [1] => Array ( [0] => 7 ) [2] => Array ( [0] => 16 ) ) 16 (2)
Array ( [0] => Array ( [0] => 2 [1] => 3 ) [1] => Array ( [0] => 8 ) ) 8 (1)
Array ( [0] => Array ( [0] => 2 [1] => 3 ) [1] => Array ( [0] => 8 ) [2] => Array ( [0] => 17 ) ) 17 (2)
Array ( [0] => Array ( [0] => 2 [1] => 3 ) [1] => Array ( [0] => 8 ) [2] => Array ( [0] => 18 ) ) 18 (2)

And then, this is what the function returns:

$data = p1() returns: Array ( [0] => Array ( [0] => 2 ) )

That is then fed into $data = p2(), which returns: Array ( [0] => Array ( [0] => 2 [1] => 3 ) )

As you can see, it is only returning the first item in the array, whereas I need the whole thing.

A co-worker suggested using a counter instead of letting it run unlimited (in the case of infinite parents) and letting the end of the counter be the escape clause, which would probably be the wise thing to do, but I would like to try to solve this issue first before resorting to other tactics, unless this looks like a total lost cause.

Another co-worker suggested I wasn’t returning the array, I was returning a reference point to the array. This is possible but I thought you could return arrays with php…?

The other possibility I thought of is that the return part of the function is just not in the right place and is returning the array too early, though I have no idea where it should be if this is the case.

So my question is a two-parter:

  1. Does anyone know of a solution to this issue?
  2. Is it madness and should I opt out and try my co-worker’s suggestion? Would this also return only part of the array instead of the whole?

p1() and p2() functions return arrays. You need to capture the return values into variables.


        p1($p2,$cnt,$array);
        p2($p2,$cnt,$array);

Other than that, I’m not sure what array structure you’re looking for.

This is ultimately what I hope to achieve:

Array ( [0] => Array ( [0] => 2 
			[1] => 3 )
	 [1] => Array ( [0] => 4 
			[1] => 5 
			[2] => 7 
			[3] => 8 ) 
	 [2] => Array ( [0] => 11 
			[1] => 12 
			[2] => 13 
			[3] => 14 
			[4] => 15 
			[5] => 16 
			[6] => 17 
			[7] => 18 ) ) 

However they only return the first item in the overall array, aka this:
Array ( [0] => Array ( [0] => 2 [1] => 3 ) )

It does return it as an array but not the entire array, which is the issue.

In addition I believe I’m capturing them into variables. I’m new to PHP so I could be mistaken, but isn’t that what this is doing?

$data = p1($aid,-1,$data);
$data = p2($aid,-1,$data);

That captures this:

Array ( [0] => Array ( [0] => 2 [1] => 3 ) )

into $data. At least I think it is lol. Again, I am new to the language; please educate me if I am incorrect.