0

So every member has an intro_id, which stands for the userid of the guy who referred the member. If member 2 was referred by member 1, member 2s intro_id would be 1.

I am basically trying to "count" every ref, multiple levels deep. First level are direct referrals, second level are referrals referred by the first level refs.

Code so far:

function countReferrals($userid, $i){
    if($userid=='')
    {
       $userid=$_SESSION['member_id'];
    }
    if($i=='' || empty($i))
    {
       $i=0;
    }

    $query1 = new Bin_Query();
    $sql = "select member_id from members where intro_id='".$userid."'";
    $query1->executeQuery($sql);
    $level1Refs = $query1->records;

    foreach($level1Refs as $refer)
    {
       $i=$i+1;
       echo "<script>console.log( 'Debug Objects | countReferrals | \$i = ".$i." | \$refer[member_id] = ".$refer['member_id']."  ' );</script>";
       self::countReferrals($refer['member_id'], $i);
    }
}

This maximum output number ($i) is around 150. Sometimes 149, 146, ... First level referrals are 400+ and some in second level. So it's clearly stopping before it counts every ref, but why?

If I remove

self::countReferrals($refer['member_id'], $i);

It counts all level 1 refs. But I want refs from the other levels, too.

Dawg
  • 69
  • 9
  • have You tried to extend memory limit from php.ini ? – num8er Aug 12 '17 at 21:47
  • 1
    Please indent your code. – Casimir et Hippolyte Aug 12 '17 at 21:50
  • Debugging 101: Format your code. It's pretty rough to follow your code when it's not properly formatted, indented, etc. – random_user_name Aug 12 '17 at 21:50
  • 1
    And every question that includes SQL code like yours needs this comment: **Your code is vulnerable to SQL injection attacks**. Use prepared statements: https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php?rq=1 – random_user_name Aug 12 '17 at 21:51
  • @Carcigenicate "echo" in the foreach loop – Dawg Aug 12 '17 at 21:53
  • Is it indented for you guys? Because it was before for me. I know prepared statements are better, but it's out of my scope atm. – Dawg Aug 12 '17 at 21:55
  • Is having all of the data in your database in the hands of a third party and/or dropped in production in scope? – Preston Guillot Aug 12 '17 at 21:59
  • @Dawg, the code looks much better now. Could you add a `var_dump` of $level1Refs right before the for loop. Maybe it's not array, but an object that gets destroyed/modified during the recursive calls. – jh1711 Aug 12 '17 at 22:03
  • I'd have thought you could make 1 sql query, store the recordset in an array and then use a `RecursiveArrayIterator`? – Professor Abronsius Aug 12 '17 at 22:03
  • $i is the sum of the width and the depth of your referral tree. Your life will probably easier if you use two variables. I. e. only increment $i for each recursive call and use $j to count the iterations of the `for` loop. – jh1711 Aug 12 '17 at 22:12
  • @jh1711 this is the output: https://pastebin.com/D8mH9r7p an array with every ref from the first level – Dawg Aug 12 '17 at 22:27
  • 1
    Thanks @Dawg. Sadly it means my guess was wrong. The different levels in the recursion probably don't modify each other. Maybe BeetleJuice is right and there are cycles in your referral system that lead to infinite recursion? – jh1711 Aug 12 '17 at 22:36
  • @jh1711 Thanks for your time. Does that mean there are people who referred each other? Like user1 referred user2 and user2 referred user1? – Dawg Aug 12 '17 at 22:44
  • 1
    @Dawg Yes. Or longer chains like 1 referred 2 who referred 3 and 3 referred 1 again. – jh1711 Aug 12 '17 at 22:50

1 Answers1

1

Your code runs in an endless loop (or at least until PHP cuts it off), because there is no restriction on when the recursive call is made. So when you see 149 or 150, it's likely because you have gone 148 or 149 levels deep and at the root function, you are still on the very first record.

If you're interested only in n levels of depth, provide n as a parameter, and increment it every time you make a recursive call. In the function, check if n > $maxLevels return immediately.

BeetleJuice
  • 39,516
  • 19
  • 105
  • 165