How to check if the function call is first or not in recursive function?

Suppose i have following recursive function(dummy):

function someRecursiceFunc($id){	
	if(/*check_if_call_is_first*/){
		//want to do some operations here with the $id
	}
	$sql 		= "SELECT id, parent_id, title FROM some_table WHERE id = ".(int)$id;
	$db_result 	= mysql_query($sql);
	while($row 	= mysql_fetch_array($db_result)){
		someRecursiveFunc($row['parent_id']);
	}
}

i tried with the static $count = 0 & incremented in while() loop
but this caused problem in function call inside loop(as static variable preserves the value)
For example:

foreach($datas as $data){
	someRecursiveFunc($data['id']);//value of $count went increasing
}

is there any techinque so that i can check for first call?

If you only want to do the operations once, and on the first call, then they probably don’t belong in the recursive function.

That said, you could add $first = true as a param, set it false in the function, and pass it on inner recursive calls.

You can also have a try with Sessions…

is there only way to achieve this using extra parameter?
@pratip: I don’t think session is appropriate in this case
any other solutions?

The solution is not to abuse the recursive function :slight_smile: what other solutions do you want? Do you have a specific example?

This is what i want

is there any techinque so that i can check for first call?

but without using arguments.

Has anybody some hint/idea?

Perhaps you can tell us the reason behind wanting to know if it’s the first.

Then we can advise on the best practice that’s commonly used to achieve the end result.

You can use Debug facility to check what you want

You should preprocess. If it’s in a class you could use public and private methods, you really need to give an example.

But in short, this is not possible. You call the function and it creates a new scope, so you need to pass info or use globals to track counts/booleans. You could do this with return values that accumulate but I don’t think that will help with pre processing.

static. :wink:


<?php
function recursive($foo){
    static $first = null;
    $first = is_null($first) ? true : false ;
    if($first){
        #
    }
}

Although, you probably really do need to re-evaluate what you’re doing.

meh

Most thought provoking, spiritual even. :stuck_out_tongue:

Care to elaborate?

hehe

well statics don’t work … according to the op

(of course they do, as well as globals, arguments, and pre processing vars)

This code doesn’t work in the following case:

recursive(1); //works
recursive(2); //doesn't work as static variable preserves the value

Well, that’s a new requirement now isn’t it? :rolleyes:


<?php
function recursive($id){
    static $already_processed = array();
    if(false === in_array($id, $already_processed)){
        array_push($already_processed, $id);
        
        #first iteration
        printf('Processing id &#37;d', $id);
    }else{
        #subsequent iteration
    }
}

recursive(1);
recursive(2);
recursive(1);
recursive(2);
recursive(3);
recursive(2);
recursive(2);
recursive(4);

/*
    Processing id 1
    Processing id 2
    Processing id 3
    Processing id 4
*/

@AnthonySterling:
Finally you did it.That’s what i want.
Cheers.

Another Question:
is there any performance issues with
recursion with extra argument(as done by hash) vs static variable/array approach(as done by you)
for such case?

Any performance issues will come from using recursion itself, not an extra boolean or array.

Yes obviously, recursion itself a big issue for performace.
suppose if i had a following table structure:
id | parent_id | title |

how many rows will cause the noticeable performance issue if we used the above recursion method?

Thanks

Recursion is not necessarily a big performance issue, in general it is memory intensive, but do you have these problems? There are already a number of solutions for dealing with hierarchical data, you don’t need to reinvent the wheel.

the one way to get rid of such model is to repalce with nested set model.
But i have to use the mentioned model as the client have such db structure.
thanks