1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

Function Looping Issue

Discussion in 'PHP' started by T0PS3O, Feb 3, 2006.

  1. #1
    I needed a function which I could pass a date and a number N, which would be any given number of working days. Back out of the function I wanted the unix date stap of the 15th working day since the input date.

    I found what I needed on php.net - but didn't understand how to use it. In fact, I don't know what &$t does, the ampersand part of that.

    The comlete function I based mine on is here:

    
    /*
    $date - date (dd/mm/yyyy)
    $n - number of days
    $t - resulting timestamp
    */
    
    function getNthWorkingDay($date,$n,&$t)
    {
       $arr = array();
       list($day,$month,$year) = explode("/",$date);
    
       $ts = mktime(0,0,0,$month,$day,$year);
    
       for($i = 1; $i <= $n; $i++)
       {
           $_ts = mktime(0,0,0,$month,$day + $i,$year);
           $arr[$i - 1]["d"] = date("w",$_ts);
           $arr[$i - 1]["ts"] = $_ts;
       }
    
       $working_days = array();
       $j = 0;
    
       for($i = 1; $i <= $n; $i++)
       {
           if($arr[$i - 1]["d"] != 6 AND $arr[$i - 1]["d"] != 0)
           {
               $working_days[$j]["d"] = $arr[$i - 1]["d"];
               $working_days[$j]["ts"] = $arr[$i - 1]["ts"];
               $j++;
           }
       }
    
       if(sizeOf($working_days) >= $n)
       {
           $t = $working_days[sizeOf($working_days) - 1]["ts"];
       }
       else
       {
           $_n = $n - sizeOf($working_days);
          
           getNthWorkingDay(date("d/m/Y",$arr[$n-1]["ts"]),$_n,$t);
       }
    }
    ?>
    
    PHP:
    So I hacked that into:

    
    function tep_get_Nth_working_day($date,$n)
    {
       $arr = array();
    
       $day = date("d", $date);
       $month = date("m", $date);
       $year = date("Y", $date);
       
       //echo '<br>' . $day . ' - ' . $month . ' - ' . $year;
    
       $ts = mktime(0,0,0,$month,$day,$year);
    
       for($i = 1; $i <= $n; $i++)
       {
           $_ts = mktime(0,0,0,$month,$day + $i,$year);
           $arr[$i - 1]["d"] = date("w",$_ts);
           $arr[$i - 1]["ts"] = $_ts;
       }
    
       $working_days = array();
       $j = 0;
    
       for($i = 1; $i <= $n; $i++)
       {
           if($arr[$i - 1]["d"] != 6 AND $arr[$i - 1]["d"] != 0)
           {
               $working_days[$j]["d"] = $arr[$i - 1]["d"];
               $working_days[$j]["ts"] = $arr[$i - 1]["ts"];
               $j++;
           }
       }
    //echo '<br>' . $working_days[sizeOf($working_days) - 1]["ts"];
       if(sizeOf($working_days) >= $n)
       {
       	   $x = sizeOf($working_days) - 1;
       	   $t = $working_days[$x]["ts"];
           
           //echo '<br>T:' . $t . ' and sizeof:' . sizeOf($working_days) - 1;
           
           //echo '<pre>';
       	   //print_r($working_days);
       	   //echo '</pre>';
           
       	   echo '<br>T: ' . $t;
       	   
           return $t;
       }
       else
       {
           $_n = $n - sizeOf($working_days);
          
           tep_get_Nth_working_day($arr[$n-1]["ts"],$_n);
       }
       
       
    
    }
    
    PHP:
    Problem is... $t echoes just nicely but it never returns anything. Line 44 in this example actually give me what I want but I can't get it out of the function.

    
    $unix_date_tim = 1140480000;
    echo tep_get_Nth_working_day($unix_date_time, 15);
    
    PHP:
    Nothing...

    It's probably due to the looping i.e. within the function it calls itself again.

    What is that &$t? How do I get this function to trow me back $t instead of returning nothing?
     
    T0PS3O, Feb 3, 2006 IP
  2. T0PS3O

    T0PS3O Feel Good PLC

    Messages:
    13,219
    Likes Received:
    777
    Best Answers:
    0
    Trophy Points:
    0
    #2
    I tried to re-include the &$t thing, whatever it may be, but keep getting "Only variables can be passed by reference in".

    Considering the original function isn't even returning any value, how is it supposed to work?
     
    T0PS3O, Feb 3, 2006 IP
  3. wwm

    wwm Peon

    Messages:
    308
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #3
    in php 4 addin an anpersand & infront of a variable / objects

    makes the variable be passed by reference not passed by value

    its a hard concept to explain, have you ever heard of pointers (These are used extensively in C and C++)

    passing by reference is more efficient but has some problems

    in php5 they do away with this ampersand mess and al values are passed by reference
     
    wwm, Feb 3, 2006 IP
  4. wwm

    wwm Peon

    Messages:
    308
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #4
    ok i pasted the code onto test file on my pc

    can u paste where in php.net u got this code from i want to see the bigger picture :)

    thats called recursion

    below is the code i pasted into test.php

    <?php
          function tep_get_Nth_working_day($date,$n)
      
          {
     
             $arr = array();
     
           
    
             $day = date("d", $date);
     
             $month = date("m", $date);
     
             $year = date("Y", $date);
    
             echo '<br>' . $day . ' - ' . $month . ' - ' . $year;
    
           
     
             $ts = mktime(0,0,0,$month,$day,$year);
    
           
    
             for($i = 1; $i <= $n; $i++)
     
             {
     
                 $_ts = mktime(0,0,0,$month,$day + $i,$year);
     
                 $arr[$i - 1]["d"] = date("w",$_ts);
     
                 $arr[$i - 1]["ts"] = $_ts;
    
             }
    
             $working_days = array();
     
             $j = 0;
    
           
    
             for($i = 1; $i <= $n; $i++)
     
             {
     
                 if($arr[$i - 1]["d"] != 6 AND $arr[$i - 1]["d"] != 0)
    
                 {
    
                     $working_days[$j]["d"] = $arr[$i - 1]["d"];
     
                     $working_days[$j]["ts"] = $arr[$i - 1]["ts"];
     
                     $j++;
     
                 }
     
             }
     
          echo '<br>' . $working_days[sizeOf($working_days) - 1]["ts"];
      
             if(sizeOf($working_days) >= $n)
     
             {
                 $x = sizeOf($working_days) - 1;
    
                 $t = $working_days[$x]["ts"];
    
                 echo '<br>T:' . $t . ' and sizeof:' . sizeOf($working_days) - 1;
    
                 echo '<pre>';
    
                 print_r($working_days);
    
                 echo '</pre>';
    
    
                 echo '<br>T: ' . $t;
    
                 return $t;
    
             }
    
             else
     
             {
     
                 $_n = $n - sizeOf($working_days);
    
                 tep_get_Nth_working_day($arr[$n-1]["ts"],$_n);
    
             }
             
             
    
          } 
          
          
     
          $unix_date_tim = 1140480000;
    
          echo tep_get_Nth_working_day($unix_date_time, 15); 
     ?>
    PHP:
    heres what output i got using PHP 5.1 and i run this script using php 4.4 as well with same result

    
    01 - 01 - 1970
    1292400
    16 - 01 - 1970
    1638000
    20 - 01 - 1970
    1810800-1
    
    Array
    (
        [0] => Array
            (
                [d] => 3
                [ts] => 1724400
            )
    
        [1] => Array
            (
                [d] => 4
                [ts] => 1810800
            )
    
    )
    
    
    T: 1810800
    PHP:
     
    wwm, Feb 3, 2006 IP
    T0PS3O likes this.
  5. forkqueue

    forkqueue Guest

    Messages:
    401
    Likes Received:
    21
    Best Answers:
    0
    Trophy Points:
    0
    #5
    You answered yourself in the question, it's passing by reference.

    You can use the original example like this

    
    getNthWorkingDay("12/05/06",15,$t);
    
    print $t;
    
    Code (markup):
    Works for me..
     
    forkqueue, Feb 3, 2006 IP
    T0PS3O likes this.
  6. T0PS3O

    T0PS3O Feel Good PLC

    Messages:
    13,219
    Likes Received:
    777
    Best Answers:
    0
    Trophy Points:
    0
    #6
    wwm, got the function from here: http://uk.php.net/manual/en/function.date.php Search "working" on that page and it will jump straight down. The person who wrote didn;t supply an example.

    Not how in your output, it doesn't do the last echo.

    Forqueue, tried it and it worked!

    Never knew it could work like that! So I basically tell te function, via the 3d argument, "I want your output back in a global variable called $t". Run the function (which doesn't use 'return') and just echo $t! Wow!

    As simple as that... Quite amazed really.. The things you can learn when others are in the pub :D Thanks!
     
    T0PS3O, Feb 3, 2006 IP
  7. wwm

    wwm Peon

    Messages:
    308
    Likes Received:
    10
    Best Answers:
    0
    Trophy Points:
    0
    #7
    found the function on php.net

    sometimes i wonder why do some people on php.net write the most obscure code ever!
    without comments and examples either!

    :)
     
    wwm, Feb 3, 2006 IP
  8. T0PS3O

    T0PS3O Feel Good PLC

    Messages:
    13,219
    Likes Received:
    777
    Best Answers:
    0
    Trophy Points:
    0
    #8
    I even e-mailed the poor guy earlier today... Will probably be rather annoyed with such a n00b question :D

    However, up until this guy, I had all my OS queries answered by the code providers when I sniffed out their e-mail address on the net and mailed them. As quick as just a few hours even. The after 'sales' service you sometimes get is astonishing, even better than some paid for software. Just goes to show... If you don't ask, you don't get.

    Not that I'm some kind of selfish bastard. I helped people on osCommerce who turned out to be competitors! (Next time I'll ask what they sell first... Live and learn.)
     
    T0PS3O, Feb 3, 2006 IP
  9. forkqueue

    forkqueue Guest

    Messages:
    401
    Likes Received:
    21
    Best Answers:
    0
    Trophy Points:
    0
    #9
     
    forkqueue, Feb 5, 2006 IP