Hello,

I am struggling with successfully have a function call itself to populate an array with unique values.

The code works without the recursions but I will include the entire code body for the function here here as it is fairly small.
I have changed the url values to pseudo server and url however.

So what i need to do is to fully populate the array name $iarray() so this is a global scope value.
Also the variable $passes which is changed based on recursion level and $passesallowed which is set only once and passed down.

The one other stipulation is that I need to stop the recursion at a specified level or passes say counting levels down to 3 or 4 deep.

I look to populate the $iarray with an $id value. The $ascend value is used to determine last positions
and if the $ascend number is greater than 255 the recursion occurs ($ascend can go up to a value of 512).

Here is my coding and I do appreciate any help with this. Perhaps my folly is not having this as a class?

Any way here is my code

<?php
session_start();
include ("mycurl.php");
extract($_POST);
$server = "https://mystuff.com";
$iarray = array();
$passcnt = 0;

function get_ids($server, $id, &$passcnt, $passesallowed, &$iarray) {
	if ($passcnt <= $passesallowed) {
	  $httpurl = $server."/get_levels/getinfo=8";
	  $jsondata=http($httpurl, $_SESSION['token']);
          $json_a=json_decode($jsondata,true);

	foreach($json_a['persons'] as $p) {
			$mid = $p['id'];
	    if (strlen($mid) == 8) { 
	      $ascend = $p['display']['ascendancyNumber'];
	      if (!in_array($mid, $iarray)) {
					array_push($iarray, $mid);  
	        if ($ascend > 255) {
	          if ($passcnt == 0) { $passcnt += 1; }
	          get_ids($server, $mid, $passcnt, $passesallowed, $iarray)
					}	 
	      }
	    }
	  }
	}
}

get_ids($server, $id, $passcnt, ceil($_SESSION['deep']/9), $iarray)

/?>

Thank you very much for any help in getting this to process properly.

Kim

    the only issue I see is your pass count - you only increment it if it is zero. IIUC, you should be incrementing it on every pass, regardless.

    I might also suggest making it a static variable, so the function can mange it itself without needing a value to be passed in.

    function staticCounter( $allowedPasses ){
        static $currentPass;
        if( $currentPass < $allowedPasses ){
            $currentPass++;
            print "$currentPass\n";
            staticCounter( $allowedPasses );
        }
        else{
            print "all done: $allowedPasses passes.";
        }
    }

    As far as [font=monospace]$iarray[/font] is concerned, you're passing it as a reference, so it will be available in the scope you called the function from (which may be the global scope; I don't know). If you really need it to be global (which is usually not necessary, and not recommended in general), you can create it as a global variable (e.g., using [font=monospace]$GLOBALS[/font]) before you pass it to the function (or afterwards, I suppose).

    If there's something I'm missing (I couldn't test your code, obviously, since it relies on other functions and on specific data), please explain further.

      khovorka;11034123 wrote:
      extract($_POST);
      $server = "https://mystuff.com";
      

      In general, do not use extract. In particular, if you do not immediately understand what could happen if you reversed the above two lines, i.e.

      $server = "https://mystuff.com";
      extract($_POST);
      

      then you should never ever use it. If you do understand what could happen, I go back to my first point: Do not use it. It's dangerous, error prone and your IDE will not be able to keep track of what variables are available. If you do not use such and IDE, I recommend that you start doing so.

      khovorka;11034123 wrote:

      I am struggling with successfully have a function call itself to populate an array with unique values.

                  $mid = $p['id'];
                  if (strlen($mid) == 8) {
                      $ascend = $p['display']['ascendancyNumber'];
                      if (!in_array($mid, $iarray)) {
                          array_push($iarray, $mid);
      

      Considering that you only ever assign something to the array once, when the value isn't already there, and the only thing you put in there is the $mid… there is no point at all for the recursion you are doing. Moreover, each time the function is called, it will request the exact same external resource. Or so I'm guessing from the fact that you always call http() with the exact same parameters. Since you seem to be fond of external variables, it's of course entirely possible that you keep overwriting some global which is used inside http(), but if that's the case, this is the first part of the code I'd change - to not use globals.

      khovorka;11034123 wrote:

      The code works without the recursions

      Yes, if all you want to do is put unique $mid in the array, you are already doing so. Putting the same unique values into the same container over and over will not change these results.

      Which begs the question why you "want recursion"?

      khovorka;11034123 wrote:

      So what i need to do is to fully populate the array name $iarray()

      which you already have done, no?

      khovorka;11034123 wrote:

      so this is a global scope value.

      Which you should not do. At least not outside of global scope. And since you pass $iarray by reference, the calling code will have $iarray changed. Thus, if you call get_ids from global scope, then $iarray resides in global scope and you have achieved what you ask for. If you call get_ids from some other scope, then $iarray will be updated in whatever that particular scope happen to be. Should you still need to propagate this to its calling scope (which may or may not be global), then it's the responsibility of that scope to somehow return the value into the scope of its caller. For example by returning the value from within a function.

      khovorka;11034123 wrote:

      The one other stipulation is that I need to stop the recursion at a specified level or passes say counting levels down to 3 or 4 deep.

      Once again, I recommend stopping the recursion before you even start it, seeing as it is pointless.

      khovorka;11034123 wrote:

      I look to populate the $iarray with an $id value. The $ascend value is used to determine last positions
      and if the $ascend number is greater than 255 the recursion occurs ($ascend can go up to a value of 512).

      And since you do nothing with $ascend, except determin if you should recurse, which you shouldn't, you may drop its usage alltogether.

        There's also the fact that [font=monospace]$passcnt[/font] will never equal 2...

          Write a Reply...