PHP Ссылочная переменная при работе с рекурсивной функцией - PullRequest
0 голосов
/ 28 марта 2020

У меня есть 2 функции рекурсии для расчета начального и конечного запасов.

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());
}

По сути, эти две функции рассчитывают запас от ограниченного нижнего времени до ограниченного верхнего времени. Например, нижний предел ограничен 16 декабря 2019 года, а верхний ограничен 31 марта 2020 года. Таким образом, они рассчитают начальный и конечный запасы марта.


$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
);

Проблема в том, что после запуска getOpeningStock Функция my 2 Переменная $lower и upper были изменены, они не сохраняют исходное значение, которое я установил в начале. Вы можете увидеть разницу в комментарии в моем коде выше. В чем причина разницы?

Спасибо!

1 Ответ

1 голос
/ 28 марта 2020

Клонируйте $lower и $upper и вызывайте $addPeriod() и $subPeriod() для клонированных копий, которые вы затем передаете рекурсивно:

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());
}
...