0

Hello, I have been strugling with this for a while. Is it possible to create a loop that will make this function run automaticly. I want to type in how many times it should repeat the pattern.
For example, i want to run to $sum20
Please help me out!

<?php
    $sum = $ROI*$start_balance;
    $sum2 = $ROI*$sum;
    $sum3 = $ROI*$sum2;
    $sum4 = $ROI*$sum3;
    $sum5 = $ROI*$sum4;
 ?>

Regards, desperate developer!

4
Contributors
6
Replies
64
Views
1 Month
Discussion Span
Last Post by diafol
1

Hi,

you can use a for() loop and the assignment operator *=, for example:

<?php

function _sum($start_balance = 0, $stop = 1, $roi = 1)
{
    for($i = 0, $sum = $start_balance * $roi; $i < $stop - 1; $sum *= $roi, $i++) { }
    return $sum;
}

print _sum(2, 5, 5);

But if you plan to use floats or to produce big numbers, then you have to change approach, use BCMath or GMP and read carefully about floating point quirks (which BCMath solves):

1

Ah, no. Okay for that you need variable variables:

For example:

<?php

$start_balance = 2;
$stop = 5;
$roi  = 5;
$sum  = 0;

for($i = 1; $i <= $stop; $i++)  
{
    if(1 == $i)
        $sum = $roi * $start_balance;

    elseif(2 == $i)
        ${'sum' . $i} = $roi * $sum;

    else
        ${'sum' . $i} = $roi * ${'sum' . ($i - 1)};
}

print_r(get_defined_vars()) . PHP_EOL;

Which prints, among the other variables:

[sum]  => 10
[sum2] => 50
[sum3] => 250
[sum4] => 1250
[sum5] => 6250

Which means the loop defined these variables $sum, $sum2, ..., $sum5. If you want to use a function, then keep in mind that the variables will be set in the function scope, so these won't be available outside, unless you set them global:

function _sum($start_balance = 0, $stop = 1, $roi = 1)
{
    for($i = 1; $i <= $stop; $i++)  
    {
        if(1 == $i)
        {
            global $sum;
            $sum = $roi * $start_balance;
        }

        elseif(2 == $i)
        {
            global ${'sum' . $i};
            ${'sum' . $i} = $roi * $sum;
        }

        else
        {
            global ${'sum' . $i};
            ${'sum' . $i} = $roi * ${'sum' . ($i - 1)};
        }
    }
}

_sum(2, 5, 5);

If you explain why you need it like this, maybe we can suggest a better solution.

Edited by cereal

Votes + Comments
+ for making a solution with variable variables. This same approach can be done with an array resulting cleaner code and easier maintenance
0

So I'm building a Return on investement application. It will all be outputted in a table to the user.
For each projection sum there will be a journal item attached. That journal items are located in a diffrent table in the db.
To fetch the journal data i need to run a foreach loop, and to get the projection data i need to run a while loop. And i can't run a foreach loop inside a while loop. My code looks like this:

    <?php

$user_id = escape($data->id);
    $db = new PDO('mysql:host=127.0.0.1;dbname=journal','root', '');
    $journals = $db->query("
        SELECT id, journal_date, balance
        FROM journals 
        WHERE user_id = '$user_id'
         ORDER BY journal_date ASC ")->fetchAll(PDO::FETCH_ASSOC);

                $pj = new PROJECTIONS();
                $start_balance;
                $ROR;
                $projector = DB::getInstance()->get('projection', array('user_id', '=', escape($data->id)));
                if($projector->count()){
                     $start_balance = $projector->first()->start_balance;
                     $ROR = $projector->first()->ROR;
                } 
                $ROI; //Turns a 5% into a 1.05 or a 10% into a 1.10 so I can just multiply them with the start balance
                if($ROR >'9'){
                    $ROI = '1.'.$ROR;
                } else {
                     $ROI = '1.0'.$ROR;
                }?>

<table class="table table-hover">
 <tr>
   <th>Day</th>
   <th>Projection Balance</th>
   <th>Actual Balance</th>
   <th>Date</th>
   <th>Journal</th>
 </tr>
    <?php
        $x = 1;
        while($x<10){
            $sums = $pj->_sum($start_balance, $x, $ROI);
    ?>
    <tr>
        <td><?php echo $x;?></td>
        <td>$<?php echo round($sums,2); ?></td>
        <td>Show Journal Balance</td> 
        <td>Show journal date</td>
        <td>journal item link</td>
    </tr> 
    <?php
        $x++;
    }
    ?> 
</table>

                            <?php if(!empty($journals)){
                                 foreach($journals as $journal){
                                     $journalItem = array( $journal['id'], $journal['journal_date'], $journal['balance']); 
                                 }

                            }
                ?>
0

I think you need use left join and make all calculations in SQL. Something like this:

SELECT
    j.id
    ,j.journal_date
    ,j.balance
    ,COUNT(p.projection)
    -- calculate here
FROM
    journals j
LEFT JOIN
    projects p on j.user_id = p.user_id
WHERE
    j.user_id = '$user_id'
ORDER BY
    j.journal_date ASC

Edited by AndrisP

0

If $ROR can be a float (you describe it as a string in your code - bit weird). You wrote this:

            if($ROR >'9'){
                $ROI = '1.'.$ROR;
            } else {
                 $ROI = '1.0'.$ROR;
            }    

If $ROR can be 9.3, $ROI will be 1.9.3, which doesn't make sense. Again you are casting $ROI as a string, but you say that you want to use it as a multiplier. PHP is very forgiving, but try keeping to the correct type.

A better conversion (IMO) would be:

$ROI = (100 + $ROR)/100; //no need for a conditional and works with negative $RORs too
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.