【问题标题】:php a better way of calculating number of daysphp 一种更好的计算天数的方法
【发布时间】:2017-08-22 12:34:42
【问题描述】:

家庭控制器:

//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 循环变得非常长而且非常难看。所以我的问题是如何以更好、更有效的方式做到这一点。

【问题讨论】:

  • 那么使用另一个循环...?
  • 那么我将有 3 个嵌套循环。可以举个例子吗?
  • 首先规范化表格价格我看到你使用explode('|',$availables[$i]['persons']); ...表明设计不好..如果你规范化表格,你可以在你的数据库上进行价格计算,因为它应该是
  • “那么我将有 3 个嵌套循环” - 所以?你这么说好像它意味着什么...... “你能举个例子吗?” - 不,首先你尝试一些东西并向我们展示......(你需要使用一个临时变量要先组装数据,您不能再使用$price_per_person[] = array(... 一次性完成。)
  • 此价格有效的人数,以管道符号分隔我无法正常化。否则我可以在 sql 查询中做。这就是我问的原因。

标签: php mysql symfony


【解决方案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。 else 变得无用,并且数组被一次性填充,因为 $amount 的值因情况而异。

要短得多,但还没有结束。 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。

这是在不失去清晰度的情况下尽可能简短。此外,通过删除冗余,您可以立即更新您的代码,而不是 - 尝试 - 更新每次出现的 - 大致相同的代码。

【讨论】:

  • 非常感谢您的回答
  • 你能帮我解答一下我的问题吗here我真的有货。如果我做到这一点,我可以找到一份工作
猜你喜欢
  • 2017-09-01
  • 2012-08-02
  • 1970-01-01
  • 1970-01-01
  • 2018-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多