Php 调试帮助!我一直在这里捡垃圾(有时)

Php 调试帮助!我一直在这里捡垃圾(有时),php,Php,有时,当我使用此函数的输入(日期)时,会收到垃圾,说明: <?php function optimized_subscription_total($active_sub_time,$arr_sub_values) { // This function takes a row from the DB where prices for each period of time usage is listed. there are prices for 1 month, 3 mon

有时,当我使用此函数的输入(日期)时,会收到垃圾,说明:

<?php 


function optimized_subscription_total($active_sub_time,$arr_sub_values)
{

    // This function takes a row from the DB where prices for each period of time usage is listed. there are prices for 1 month, 3 months,6 and 12 months.

    // when the user has subscribed for 12 months, and the user asks for a refund, after they used 9 months and 6 days for example, the system treats the refund as if they subscribed for (in months) COST_6 + COST_3 + (COST_1/30)*6 
    // the result of the function is then subtracted from the amount they actually paid and is considered the refund.

    // $arr_sub_values is the associative row from the DB, containing the prices
    // $active_sub_time is measured in months and is a double

    $result=0;
    if(($active_sub_time-6)>=0)
    {
        $active_sub_time-=6;
        $result+=($arr_sub_values['COST_6']);
    }
    if(($active_sub_time-3)>=0)
    {
        $active_sub_time-=3;
        $result+=($arr_sub_values['COST_3']);
    }

    while(($active_sub_time-1)>=0)
    {
        $active_sub_time-=1;
        $result+=($arr_sub_values['COST_1']);
    }

    if($active_sub_time>0)
        $result+=($active_sub_time)*($arr_sub_values['COST_1']);

    return $result;
}



$datetime1 = date_create('2009-12-11');
$datetime2 = date_create('2010-11-09');
$interval = date_diff($datetime1, $datetime2);
$num_of_months = ($interval->format('%y'))*12+($interval->format('%m'))+($interval->format('%a'))/30;
echo "<br />";

$v = array('COST_1'=>'3.99','COST_3'=>'9.99','COST_6'=>'15.99','COST_12'=>'25.99');
echo "OPT value for $num_of_months months=" . optimized_subscription_total($num_of_months, $v);


?>
因此,在这里。我想我需要一个浮点数,不是吗

我期望函数的结果应该是“10个月的OPT值=29.97”,因为它应该是COST_6+COST_3+COST_1。。。但我得到了奇怪的M.97,有时还有类似Pokhhg.97的东西

下面是重写的相同函数:

    function optimized_subscription_total($active_sub_time,$arr_subscription_values)
{

    $result=0;


while(($active_sub_time-12)>=0)
{
    $active_sub_time-=12;
    $result+=($arr_subscription_values['COST_12']);
}

if(($active_sub_time-6)>=0)
{
    $active_sub_time-=6;
    $result+=($arr_subscription_values['COST_6']);
}
if(($active_sub_time-3)>=0)
{
    $active_sub_time-=3;
    $result+=($arr_subscription_values['COST_3']);
}

while(($active_sub_time-1)>=0)
{
    $active_sub_time-=1;
    $result+=($arr_subscription_values['COST_1']);
}

if($active_sub_time>0)
    $result+=($active_sub_time)*($arr_subscription_values['COST_1']);

return $result;
}

我只是希望这不会破裂。但是有人能告诉我第一个版本有什么问题吗? 那会是什么


编辑:我在刷新页面大约10次后出现了这个错误,现在我得到了一个奇怪的I.004
谢谢

假设一个月有31天(事实并非如此),你想要完成的事情是相当容易的。DateTime::diff()假定是这样的。不过,你可能想把二月的28天当作一个完整的月份

<?php

function calculateRealCost($started, $ended) {
    // month values
    $_month = array(
        12 => 25.99,
        6 => 15.99,
        3 => 9.99,
        1 => 3.99
    );
    // assuming a median of 30 days per month. 
    // it's closer to 30.4 days per month, though.
    $_day = $_month[1] / 30;

    $price = 0;

    // identify the time span
    $started = $started instanceof DateTime ? $started : new DateTime($started);
    $ended = $ended instanceof DateTime ? $ended : new DateTime($ended);
    // you should note that diff() treat's the last day inclusive, so it may be "a day short"
    $diff = $started->diff($ended);

    // add years (12 months)
    $price += $_month[12] * $diff->y;

    // add months
    $months = $diff->m;
    foreach ($_month as $m => $v) {
        while ($m <= $months) {
            $price += $v;
            $months -= $m;
        }
    }
    // add days
    $price += $_day * $diff->d;

    // return rounded to two decimals
    return round($price, 2);
}

$test = array(
    // 0 years 10 months, 29 days
    // 15.99 + 9.99 + 3.99 + (0.133 * 29)
    array('start' => "2009-12-11", 'end' => "2010-11-09", 'cost' => 33.83),
    // 1 years 10 months, 27 days 
    // 25.99 + 15.99 + 9.99 + 3.99 + (0.133 * 27)
    array('start' => "2009-12-11", 'end' => "2011-11-07", 'cost' => 59.55),
    // 0 years 0 months, 28 days
    // (0.133 * 28)
    array('start' => "2011-02-01", 'end' => "2011-03-01", 'cost' => 3.72), 
    // 0 years 0 months, 29 days
    // (0.133 * 29)
    array('start' => "2012-02-01", 'end' => "2012-03-01", 'cost' => 3.86), 
    // 0 years 1 months, 29 days
    // 3.99 + (0.133 * 29)
    array('start' => "2011-09-01", 'end' => "2011-10-31", 'cost' => 7.85), 
);

foreach ($test as $t) {
    $res = calculateRealCost($t['start'], $t['end']);
    if ($res != $t['cost']) {
        echo "{$t['start']} to {$t['end']} expected {$t['cost']} but got {$res}\n";
    }
}

您在PHP5.3.3中为我编写的确切代码产生了
OPT value for 21.1 months=74.259
我在PHP5.3.5上有这个“OPT value for 210.5 months=829.965”我做错了什么吗?结果已经不同了,我只是在刷新页面7-10次后重新创建了这个bug。类似?谢谢@rodneyrehm的例子。我的函数现在正在运行(我刚刚在问题中添加了新版本),希望不会再次中断。我不知道你为什么要重写它,如果你能再解释一下,我会很高兴的。ThanksI将函数改写为(a)向您展示了一种方法,该方法可以轻松地引入4个月的价格,而无需修改任何代码。(b) 显示
$interval->格式(“%y”)
==
$interval->y
。(c) 了解
DateInterval
如何识别一个月(31天不变,这里没有日历支持。“二月”28天不被视为一个月)。你能找到我为什么会收到垃圾吗?我在刷新页面大约10次后出现了这个错误,现在我得到了一个奇怪的I.004。。。。
<?php

function calculateRealCost($started, $ended) {
    // month values
    $_month = array(
        12 => 25.99,
        6 => 15.99,
        3 => 9.99,
        1 => 3.99
    );
    // assuming a median of 30 days per month. 
    // it's closer to 30.4 days per month, though.
    $_day = $_month[1] / 30;

    $price = 0;

    // identify the time span
    $started = $started instanceof DateTime ? $started : new DateTime($started);
    $ended = $ended instanceof DateTime ? $ended : new DateTime($ended);
    // you should note that diff() treat's the last day inclusive, so it may be "a day short"
    $diff = $started->diff($ended);

    // add years (12 months)
    $price += $_month[12] * $diff->y;

    // add months
    $months = $diff->m;
    foreach ($_month as $m => $v) {
        while ($m <= $months) {
            $price += $v;
            $months -= $m;
        }
    }
    // add days
    $price += $_day * $diff->d;

    // return rounded to two decimals
    return round($price, 2);
}

$test = array(
    // 0 years 10 months, 29 days
    // 15.99 + 9.99 + 3.99 + (0.133 * 29)
    array('start' => "2009-12-11", 'end' => "2010-11-09", 'cost' => 33.83),
    // 1 years 10 months, 27 days 
    // 25.99 + 15.99 + 9.99 + 3.99 + (0.133 * 27)
    array('start' => "2009-12-11", 'end' => "2011-11-07", 'cost' => 59.55),
    // 0 years 0 months, 28 days
    // (0.133 * 28)
    array('start' => "2011-02-01", 'end' => "2011-03-01", 'cost' => 3.72), 
    // 0 years 0 months, 29 days
    // (0.133 * 29)
    array('start' => "2012-02-01", 'end' => "2012-03-01", 'cost' => 3.86), 
    // 0 years 1 months, 29 days
    // 3.99 + (0.133 * 29)
    array('start' => "2011-09-01", 'end' => "2011-10-31", 'cost' => 7.85), 
);

foreach ($test as $t) {
    $res = calculateRealCost($t['start'], $t['end']);
    if ($res != $t['cost']) {
        echo "{$t['start']} to {$t['end']} expected {$t['cost']} but got {$res}\n";
    }
}