【问题标题】:Optimizing PHP while loop优化 PHP while 循环
【发布时间】:2015-02-24 23:25:28
【问题描述】:

我在做什么:

检索可用的公寓列表并按布局进行分组 - 单间、1 卧室、2 卧室等。每个布局列出最低和最高平方英尺、最低租金,然后列出所有单个单元以及每个单元的详细信息。我附上了一张图片来展示它的样子。

问题

目前,我正在使用多个查询来获取大量床位,并为每个查询运行 while 循环。我希望对此进行优化并仅使用 1 个查询,但不确定从哪里开始。

代码

我在这里只显示 Studio 和 1 Bedroom 的循环,但我对 2 和 3 卧室查询做同样的事情。我想将这些整合为一个。任何帮助表示赞赏。

$studioQuery = $mysqli->query('SELECT * FROM properties WHERE Beds = "0" AND PropertyId = '.$propID.' AND AvailableDate <> "" ORDER BY FloorplanName');
$oneBedQuery = $mysqli->query('SELECT * FROM properties WHERE Beds = "1" AND PropertyId = '.$propID.' AND AvailableDate <> "" ORDER BY FloorplanName');
$twoBedQuery = $mysqli->query('SELECT * FROM properties WHERE Beds = "2" AND PropertyId = '.$propID.' AND AvailableDate <> "" ORDER BY FloorplanName');
$threeBedQuery = $mysqli->query('SELECT * FROM properties WHERE Beds = "3" AND PropertyId = '.$propID.' AND AvailableDate <> "" ORDER BY FloorplanName');

// Studio
if($studioQuery->num_rows > 0) {
    echo '<div class="layout">';
    $studioCount = 0;
    $highSqFt = 0;
    $markupStudio = '';
    while ($row = mysqli_fetch_assoc($studioQuery)) {

        $aptID = $row['ApartmentId'];

        // Get the lowest square footage
        if($studioCount == 0){
            $lowSqFt = $row['SQFT'];
            $lowRent = $row['MinimumRent'];
        }
        if($lowSqFt > $row['SQFT']){
            $lowSqFt = $row['SQFT'];
        }
        // Get the highest square footage
        if($highSqFt < $row['SQFT']){
            $highSqFt = $row['SQFT'];
        }
        // Get the lowest Rent
        if($lowRent > $row['MinimumRent']){
            $lowRent = $row['MinimumRent'];
        }

        $markupStudio .= '<div class="row unit">';
        $markupStudio .= '<div class="col-sm-15">'. $row['Beds'] .' Bed / '. $row['Baths'] .' Bath</div>';
        $markupStudio .= '<div class="col-sm-15">'. $row['ApartmentName'] .'</div>';
        $markupStudio .= '<div class="col-sm-15">$'. $row['MinimumRent'] .'</div>';
        $markupStudio .= '<div class="col-sm-15">'. $row['AvailableDate'] .'</div>';
        $markupStudio .= '<div class="col-sm-15 apply-col"><a href="'. $row['ApplyOnlineURL'] .'" target="_blank">Apply ></a></div>';
        $markupStudio .= '</div>';

        $studioCount++;
    }
    ?>

    <div class="row floorplan-header">
        <div class="col-sm-3"><div><h3>Studio</h3></div></div>
        <div class="col-sm-3 sq-ft-col"><div><?php echo $lowSqFt .' - '. $highSqFt .' SQ. FT.'; ?></div></div>
        <div class="col-sm-3 from-price-col"><div>FROM $<?php echo $lowRent; ?></div></div>
        <div class="col-sm-3 available-col"><div>Check Availability <span class="icon-caret-right"></span></div></div>
    </div>

    <div class="row unit-list">
        <div class="col-lg-12">
            <div class="row unit-header">
                <div class="col-sm-15">Type</div>
                <div class="col-sm-15">Unit#</div>
                <div class="col-sm-15">Rent</div>
                <div class="col-sm-15">Available</div>
            </div>
            <?php echo $markupStudio; ?>
        </div>
    </div>

    <?php echo '</div>';
}

// 1 Bedroom
if($oneBedQuery->num_rows > 0) {
    echo '<div class="layout">';
    $oneBedCount = 0;
    $highSqFt = 0;
    $markupOne = '';
    while ($row = mysqli_fetch_assoc($oneBedQuery)) {

        $aptID = $row['ApartmentId'];

        // Get the lowest square footage
        if($oneBedCount == 0){
            $lowSqFt = $row['SQFT'];
            $lowRent = $row['MinimumRent'];
        }
        if($lowSqFt > $row['SQFT']){
            $lowSqFt = $row['SQFT'];
        }
        // Get the highest square footage
        if($highSqFt < $row['SQFT']){
            $highSqFt = $row['SQFT'];
        }
        // Get the lowest Rent
        if($lowRent > $row['MinimumRent']){
            $lowRent = $row['MinimumRent'];
        }

        $markupOne .= '<div class="row unit">';
        $markupOne .= '<div class="col-sm-15">'. $row['Beds'] .' Bed / '. $row['Baths'] .' Bath</div>';
        $markupOne .= '<div class="col-sm-15">'. $row['ApartmentName'] .'</div>';
        $markupOne .= '<div class="col-sm-15">$'. $row['MinimumRent'] .'</div>';
        $markupOne .= '<div class="col-sm-15">'. $row['AvailableDate'] .'</div>';
        $markupOne .= '<div class="col-sm-15 apply-col"><a href="'. $row['ApplyOnlineURL'] .'" target="_blank">Apply ></a></div>';
        $markupOne .= '</div>';

        $oneBedCount++;
    }
    ?>

    <div class="row floorplan-header">
        <div class="col-sm-3"><div><h3>1 Bedroom</h3></div></div>
        <div class="col-sm-3 sq-ft-col"><div><?php echo $lowSqFt .' - '. $highSqFt .' SQ. FT.'; ?></div></div>
        <div class="col-sm-3 from-price-col"><div>FROM $<?php echo $lowRent; ?></div></div>
        <div class="col-sm-3 available-col"><div>Check Availability <span class="icon-caret-right"></span></div></div>
    </div>

    <div class="row unit-list">
        <div class="col-lg-12">
            <div class="row unit-header">
                <div class="col-sm-15">Type</div>
                <div class="col-sm-15">Unit#</div>
                <div class="col-sm-15">Rent</div>
                <div class="col-sm-15">Available</div>
            </div>
            <?php echo $markupOne; ?>
        </div>
    </div>

    <?php echo '</div>';
}

/* 编辑 */

所以现在我有一个查询,但我的逻辑在 while 循环中是关闭的。它现在打印出正确数量的 Floorplan 标题,但仅显示 1 Bedroom 下的第一个可用单元,然后它在 2 Bedroom 标题下列出所有可用的 1 Bedroom 单元,并且仅列出第一个可用的 2 Bedroom 单元。以下是更新后的代码。

$bedQuery = $mysqli->query('SELECT * FROM properties WHERE PropertyId = '.$propID.' AND AvailableDate <> "" ORDER BY Beds, FloorplanName');

// Floorplans
if($bedQuery->num_rows > 0) {

    $bedCount = 0;
    $highSqFt = 0;
    $markup = '';
    $previous = 0;

    while ($row = mysqli_fetch_assoc($bedQuery)) {

        $bedCount = $row['Beds'];
        $aptID = $row['ApartmentId'];

        // Get the lowest square footage
        if($previous == 0){
            $lowSqFt = $row['SQFT'];
            $lowRent = $row['MinimumRent'];
        }
        if($lowSqFt > $row['SQFT']){
            $lowSqFt = $row['SQFT'];
        }
        // Get the highest square footage
        if($highSqFt < $row['SQFT']){
            $highSqFt = $row['SQFT'];
        }
        // Get the lowest Rent
        if($lowRent > $row['MinimumRent']){
            $lowRent = $row['MinimumRent'];
        }

        $markup .= '<div class="row unit">';
        $markup .= '<div class="col-sm-15">'. $row['Beds'] .' Bed / '. $row['Baths'] .' Bath</div>';
        $markup .= '<div class="col-sm-15">'. $row['ApartmentName'] .'</div>';
        $markup .= '<div class="col-sm-15">$'. $row['MinimumRent'] .'</div>';
        $markup .= '<div class="col-sm-15">'. $row['AvailableDate'] .'</div>';
        $markup .= '<div class="col-sm-15 apply-col"><a href="'. $row['ApplyOnlineURL'] .'" target="_blank">Apply ></a></div>';
        $markup .= '</div>';

        if($bedCount != $previous) {
            //echo 'Beds: '.$bedCount.'</br>';
            //echo 'Previous: '.$previous;
            echo '<div class="layout">';
        ?>

        <div class="row floorplan-header">
            <div class="col-sm-3"><div><h3><?php echo $row['Beds']; ?> Bedroom</h3></div></div>
            <div class="col-sm-3 sq-ft-col"><div><?php echo $lowSqFt .' - '. $highSqFt .' SQ. FT.'; ?></div></div>
            <div class="col-sm-3 from-price-col"><div>FROM $<?php echo $lowRent; ?></div></div>
            <div class="col-sm-3 available-col"><div>Check Availability <span class="icon-caret-right"></span></div></div>
        </div>

        <div class="row unit-list">
            <div class="col-lg-12">
                <div class="row unit-header">
                    <div class="col-sm-15">Type</div>
                    <div class="col-sm-15">Unit#</div>
                    <div class="col-sm-15">Rent</div>
                    <div class="col-sm-15">Available</div>
                </div>
                <?php echo $markup; ?>
            </div>
        </div>

        <?php echo '</div>';
        }

        $previous = $bedCount;

    }

}

【问题讨论】:

  • 查看group by
  • @developerwjk 我认为GROUP BY 在这里没有多大用处,因为他想要所有单独的条目,他只想要一个查询。

标签: php loops mysqli while-loop


【解决方案1】:

您的一个查询将通过使用in() 并将Beds 添加到order by

$studioQuery = $mysqli->query('SELECT * FROM properties WHERE Beds IN('0','1','2','3') AND PropertyId = '.$propID.' AND AvailableDate <> "" ORDER BY Beds, FloorplanName');

现在,在同一个查询中,您将获得所需的所有行,每个床位编号位于下一个之前,并且在每个床位数量中,您将按 FloorplanName 对其进行排序。

现在,当您循环浏览它们时,跟踪最后一张床的价值并与当前床的价值进行比较。当它们不再相等时,打印该部分的新标题。

【讨论】:

  • IN 在这里不是必需的......我认为他只有 WHERE 子句才能将它们分成几部分,现在他立即获取所有数据不需要。与众不同的是 ORDER BY
  • 感谢您的回复。我现在使用单个查询,但我的逻辑已关闭。我对原始帖子进行了编辑以显示更新的代码。
  • @downtomike 在if($bedCount != $previous) { 之前你忘了设置$bedCount = $rows['Bed'];
  • @downtomike 并取出 $bedCount++; 那个 var 应该由循环顶部的 $bedCount = $rows['Bed']; 设置。
  • 好的,我越来越接近完成这个了。我更新了我的代码示例并解释了现在发生的事情,但基本上它打印出正确数量的标题,但每个标题下的列表都不正确。
【解决方案2】:

我建议进行一次查询以选择所有数据,然后将其保存到以床位数为索引的数组中。

然后迭代各个顶级元素来代替当前的 while 循环

$query = $mysqli->query('SELECT * FROM properties WHERE Beds < 4 AND PropertyId = '.$propID.' AND AvailableDate <> "" ORDER BY FloorplanName');

$data=[];

while ($row = mysqli_fetch_assoc($query))
    $data[$row['beds']][]=$row;

foreach($data[0] as $studioRow)
    //studio code


foreach($data[1] as $oneBedRow)
    //onebed code

这可以最大限度地减少您的重构,并有助于将您的演示文稿与您的逻辑分开一点

【讨论】:

    猜你喜欢
    • 2016-03-18
    • 2023-03-18
    • 2011-05-14
    • 2020-06-24
    • 2018-03-01
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    • 2018-11-24
    相关资源
    最近更新 更多