user3118789
user3118789

Reputation: 609

PHP Reference variable when working with recursion function

I have 2 recursion functions to calculate opening stock and closing stock.

public function getClosingStock($previousStock, $product, $periodType, $lower, $upper)
{
    $diffPeriod = 'diffIn' . Str::plural($periodType);
    $addPeriod = "add{$periodType}";

    $totalStocked = $this->getTotalStockInPeriod($product, $periodType, $lower);
    $totalIssued = $this->getTotalIssueInPeriod($product, $periodType, $lower);

    $currentStock = $previousStock + $totalStocked - $totalIssued;

    if ($upper->$diffPeriod($lower) > 0)
    {
        $currentStock = $this->getClosingStock(
            $currentStock, $product, $periodType, $lower->$addPeriod(), $upper
        );
    }

    return $currentStock;
}
public function getOpeningStock($previousStock, $product, $periodType, $lower, $upper)
{
    $subPeriod = "sub{$periodType}";

    return $this->getClosingStock($previousStock, $product, $periodType, $lower, $upper->$subPeriod());
}

Basically, those 2 functions calculate stock from bounded lower time to bounded upper time. For example, bounded lower is December 16th, 2019 and bounded upper is March 31st, 2020. So they will calculate the opening and closing stock of March.


$lower = Carbon::parse('2019-12-16');
$upper = Carbon::parse('2020-03-31');

echo $lower->toDateString() . '<br>'; // Print out: 2019-12-16
echo $upper->toDateString() . '<br>'; // Print out: 2020-03-31

$opening = $this->getOpeningStock(
    0, $product, 'month', $lower, $upper
);

echo $lower->toDateString() . '<br>'; // Print out: 2020-02-16
echo $upper->toDateString() . '<br>'; // Print out: 2020-02-29

$closing = $this->getClosingStock(
    0, $product, 'month', $lower, $upper
);

The problem is after I run the getOpeningStock function my 2 variable $lower and upper were changed, they don't keep the origin value that I set at the beginning. You can see the difference in the comment in my above code. What is the reason cause the difference?

Thank you!

Upvotes: 0

Views: 36

Answers (1)

kmoser
kmoser

Reputation: 9273

Clone $lower and $upper, and call $addPeriod() and $subPeriod() on the cloned copies, which you then pass recursively:

public function getClosingStock($previousStock, $product, $periodType, $lower, $upper)
{
    $diffPeriod = 'diffIn' . Str::plural($periodType);
    $addPeriod = "add{$periodType}";

    $totalStocked = $this->getTotalStockInPeriod($product, $periodType, $lower);
    $totalIssued = $this->getTotalIssueInPeriod($product, $periodType, $lower);

    $currentStock = $previousStock + $totalStocked - $totalIssued;

    if ($upper->$diffPeriod($lower) > 0)
    {
    $cloned_lower = clone $lower;
    $currentStock = $this->getClosingStock(
        $currentStock, $product, $periodType, $cloned_lower->$addPeriod(), $upper
    );
    }

    return $currentStock;
}

public function getOpeningStock($previousStock, $product, $periodType, $lower, $upper)
{
    $subPeriod = "sub{$periodType}";

    $cloned_upper = clone $upper;
    return $this->getClosingStock($previousStock, $product, $periodType, $lower, $cloned_upper->$subPeriod());
}

Upvotes: 1

Related Questions