php更好的计算天数的方法

时间:2017-08-22 12:34:42

标签: php mysql symfony

家庭控制器:

//my query in repository
 public function Available (){
 $Sql= ' SELECT DISTINCT 
        a.property_id, a.date, a.minimum_stay,
        a.maximum_stay,a.quantity,
        p.duration, p.persons, p.amount, 
        p.extra_person_price, p.minimum_stay AS price_minimum_stay, 
        p.maximum_stay AS price_maximum_stay, p.weekdays 
        FROM availabilities AS a 
        JOIN prices AS p 
        ON a.property_id=p.property_id 
        WHERE a.minimum_stay >0 
        AND a.maximum_stay < 22 
        AND a.date >= p.period_from 
        AND a.date <= p.period_till

 ';
    class HomeController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */

    public function indexAction(Request $request)
    {
        $hotel_information = $this->retrieveInformationFromDB();

        return $this->render('Home/index.html.twig', array(
                'hotel_information'=>$hotel_information
            )
        );
    }


    private function retrieveInformationFromDB(){
        $em= $this->getDoctrine()->getEntityManager();
        $availables = $em->getRepository('AppBundle:Availabilities')->Available();
        $hotel_information=array();

        for($i = 0; $i< count($availables) ; $i++) {
            $date = $availables[$i]['date'];
            $duration = $availables[$i]['duration'];
            $amount = $availables[$i]['amount'];
            $extra_person_price = $availables[$i]['extra_person_price'];
            $persons = explode('|',$availables[$i]['persons']);

            $hotel_information_placeholder = $this->calculatePricePerPerson($persons, $extra_person_price, $date, $amount,$duration);
            $hotel_information = array_merge($hotel_information, $hotel_information_placeholder);

        }

        return $hotel_information;
    }

    private function calculatePricePerPerson($persons, $extra_person_price, $date, $amount,$duration){
        foreach ($persons as $person) {
            if ($person > 1) {
                $price_per_person[] = array(
                    "date" => $date,
                    "person" => $person,
                    "price_person" => number_format((($person * $extra_person_price) + $amount) / 100, 2, '.', ','),
                    "day2"=>number_format(((($person * $extra_person_price) + $amount)*2) / 100, 2, '.', ','),
                    "day3"=>number_format(((($person * $extra_person_price) + $amount)*3) / 100, 2, '.', ','),
                    "day4"=>number_format(((($person * $extra_person_price) + $amount)*4) / 100, 2, '.', ','),
                    "day5"=>number_format(((($person * $extra_person_price) + $amount)*5) / 100, 2, '.', ','),
                    "day6"=>number_format(((($person * $extra_person_price) + $amount)*6) / 100, 2, '.', ','),
                    "day7"=>number_format(((($person * $extra_person_price) + $amount)*7) / 100, 2, '.', ','),

                );

            } else {
                $price_per_person[] = array(
                    "date" => $date,
                    "person" => $person,
                    "price_person" => number_format($amount / 100, 2, '.', ','),
                    "day2"=>number_format(($amount * 2)/ 100, 2, '.', ','),
                    "day3"=>number_format(($amount * 3)/ 100, 2, '.', ','),
                    "day4"=>number_format(($amount * 4)/ 100, 2, '.', ','),
                    "day5"=>number_format(($amount * 5)/ 100, 2, '.', ','),
                    "day6"=>number_format(($amount * 6)/ 100, 2, '.', ','),
                    "day7"=>number_format(($amount * 7)/ 100, 2, '.', ',')

                );
            }
        }

        return $price_per_person;
    }

在功能私人功能calculatePricePerPerson 我正在计算一个人的价格和基于日期的天数。目前我的计算方式是这样的。问题是计算的数字是从1到21,因此我的foreach循环变得非常长而且非常难看。所以我的问题是如何以更好,更有效的方式做到这一点。

1 个答案:

答案 0 :(得分:1)

此代码有几个可以优化的冗余点。 原始代码:

private function calculatePricePerPerson($persons, $extra_person_price, $date, $amount,$duration){
        foreach ($persons as $person) {
            if ($person > 1) {
                $price_per_person[] = array(
                    "date" => $date,
                    "person" => $person,
                    "price_person" => number_format((($person * $extra_person_price) + $amount) / 100, 2, '.', ','),
                    "day2"=>number_format(((($person * $extra_person_price) + $amount)*2) / 100, 2, '.', ','),
                    "day3"=>number_format(((($person * $extra_person_price) + $amount)*3) / 100, 2, '.', ','),
                    "day4"=>number_format(((($person * $extra_person_price) + $amount)*4) / 100, 2, '.', ','),
                    "day5"=>number_format(((($person * $extra_person_price) + $amount)*5) / 100, 2, '.', ','),
                    "day6"=>number_format(((($person * $extra_person_price) + $amount)*6) / 100, 2, '.', ','),
                    "day7"=>number_format(((($person * $extra_person_price) + $amount)*7) / 100, 2, '.', ','),

                );

            } else {
                $price_per_person[] = array(
                    "date" => $date,
                    "person" => $person,
                    "price_person" => number_format($amount / 100, 2, '.', ','),
                    "day2"=>number_format(($amount * 2)/ 100, 2, '.', ','),
                    "day3"=>number_format(($amount * 3)/ 100, 2, '.', ','),
                    "day4"=>number_format(($amount * 4)/ 100, 2, '.', ','),
                    "day5"=>number_format(($amount * 5)/ 100, 2, '.', ','),
                    "day6"=>number_format(($amount * 6)/ 100, 2, '.', ','),
                    "day7"=>number_format(($amount * 7)/ 100, 2, '.', ',')

                );
            }
        }

        return $price_per_person;
    }

乍一看,似乎ifelse块中的代码非常相似,唯一的区别是额外的人物。通过关注该元素,您可以避免使用两次几乎相同的代码:

private function calculatePricePerPerson($persons, $extra_person_price, $date, $amount,$duration){
        foreach ($persons as $person) {
            if ($person > 1) {
                $amount += $person * $extra_person_price;
            }
            $price_per_person[] = array(
                "date" => $date,
                "person" => $person,
                "price_person" => number_format($amount / 100, 2, '.', ','),
                "day2"=>number_format(($amount * 2)/ 100, 2, '.', ','),
                "day3"=>number_format(($amount * 3)/ 100, 2, '.', ','),
                "day4"=>number_format(($amount * 4)/ 100, 2, '.', ','),
                "day5"=>number_format(($amount * 5)/ 100, 2, '.', ','),
                "day6"=>number_format(($amount * 6)/ 100, 2, '.', ','),
                "day7"=>number_format(($amount * 7)/ 100, 2, '.', ',')
            );
        }
        return $price_per_person;
    }

不是在if的每个分支中填充数组,而是将人员价格添加到$amount。由于$amount根据具体情况具有不同的值,因此else变得无用且数组被一次性填充。

短得多,但还没结束。条目day2day7几乎完全相同,唯一的区别是密钥末尾的数字和$amount乘以的因子。偶然的,它们在每一行中总是相同的,所以让我们把它缩小到一个循环:

private function calculatePricePerPerson($persons, $extra_person_price, $date, $amount,$duration){
        foreach ($persons as $person) {
            if ($person > 1) {
                $amount += $person * $extra_person_price;
            }
            $tmp = array(
                "date" => $date,
                "person" => $person,
                "price_person" => number_format($amount / 100, 2, '.', ',')
            );
            for ($x = 2; $x <= 7; ++$x) {
                $tmp["day$x"] = number_format(($amount * $x)/ 100, 2, '.', ',');
            }
            $price_per_person[] = $tmp;
        }
        return $price_per_person;
    }

在此步骤中,我创建了一个临时数组,其中填充了静态数据,然后是for循环,该循环将$tmp的条目添加到每个天数必须处理。然后将临时数组分配给$price_per_person[],以便一切都像在第一个版本中那样工作。而且由于现在处理了一个循环,你可以通过修改for的限制来增加或减少必须计算和显示的天数 - 目前为7。

这就是你可以得到的最短而不失清晰度。此外,通过删除冗余,您可以立即更新代码,而不是 - 尝试 - 更新 - 大致相同的代码的每次出现。