PHP foreach 循环和 Mysqli Fetch 关联数组问题(Dublicated 值)

PHP foreach Loop and Mysqli Fetch associative array problem (Dublicated values)

提问人:Demetris Demetriou 提问时间:3/30/2023 最后编辑:Demetris Demetriou 更新时间:3/31/2023 访问量:115

问:

我只需要从数据库中检查“日期被阻止”是否在选择框中显示为禁用,如果没有,则在同一选择框中显示接下来的 2 个月的所有日子。 我得到关闭(阻止)的日子没有问题,但是当我试图获得其余的日子时,我会得到双倍的一切。如果不是,则数组不工作。 结果显示如下所示:

星期四, 30 三月 , 星期四, 3月 30日 甚至第一个循环的 DISABLED day 在循环后也会显示双倍。
进一步澄清: 我正在使用 For Loop 来获取接下来 2 个月的日期。我正在使用 foreach 循环来获取包含关闭日期(周日、周一)的数组......所以我想在选择框中显示(禁用星期日或星期一的日期)并显示其余的日子正常。

我的 sql

CREATE TABLE `check_availability` (
  `id` int(10) NOT NULL,
  `Day` varchar(10) NOT NULL,
  `Open_hour` varchar(10) NOT NULL,
  `Closed_hour` varchar(10) NOT NULL,
  `ClosedDays` varchar(10) NOT NULL,
  `Blocked` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


INSERT INTO `check_availability` (`id`, `Day`, `Open_hour`, `Closed_hour`, `ClosedDays`, `Blocked`) VALUES
(1, 'Sunday', '09:00am', '10:00pm', '', 1),
(2, 'Monday', '09:00am', '10:00pm', '', 1);

Mysqli 获取代码。数组是正确的。数组 ( [0] => 数组 ( [day] => Sunday ) [1] => 数组 ( [day] => Monday ) ) 在循环浏览禁用日时,我可以正确地获得 2 个月的周日或周一的所有日期。

$sqlClosedDays   = "SELECT Day FROM check_availability WHERE Blocked ='1'";             
$resultClosed    = mysqli_query($con, $sqlClosedDays);
$DaysClosed   = mysqli_fetch_all($resultClosed,MYSQLI_ASSOC);

我的 for 和 Foreach 循环导致日期显示双倍。

echo "<select name='add_r_date' id='add_r_date'>";
for($i=0;$i<=60;$i++){

    //Get the Closed Days   
    
    //Display the Days according to limit   
    $day=date('l,d M',strtotime("+$i day"));
    $InsDay = date('Y-m-d',strtotime("+$i day"));   
    
    foreach ($DaysClosed as $rowDaysClosed) {   
        $dayClosed = $rowDaysClosed['Day'];
        $dayClosedTrim= substr($dayClosed, 0, 3);
        $dayTrim = substr($day, 0, 3);
        
        //If not Closed set as available
        if ($dayTrim === $dayClosedTrim ) { 
            echo "<option disabled value='$InsDay'>$day</option> "; 
            //$clDays[] = $day;     
        } else {
            echo "<option name='add_r_date' id='add_r_date' value='$InsDay'>$day</option>";
        }
    }//EOF FOREACH LOOP 
}//EOF FOR LOOP 
echo "</select>";

我尝试了 unset($day);或 unset($dayClosed);

我试过 Break;在循环中,但问题仍然存在。

问题是值显示 2 次。我只想在禁用中显示关闭的日子(星期日)和(星期一),并显示休息日正常,以便人们可以选择可用的日期进行预订。

PHP 数组 select foreach mysqli

评论

0赞 Nico Haase 3/30/2023
“double” 是什么意思?如果您只想显示一次日期,为什么要循环显示日期?for
3赞 CBroe 3/30/2023
当然,这是行不通的 - 当您仍在迭代该列表,您无法确定某个值不在给定列表中;只有在完成对所有项目的迭代后,才能确定这一点。使用布尔标志,当您找到匹配项时,您可以在循环中切换该标志,然后在循环做出相应的反应。
0赞 Demetris Demetriou 3/30/2023
@NicoHaase我正在使用 For Loop 来获取接下来 2 个月的日期。我正在使用 foreach 循环来获取包含关闭日期(周日、周一)的数组......所以我想在选择框中显示(禁用星期日或星期一的日期)并显示其余的日子正常。
0赞 Nico Haase 3/30/2023
请通过编辑您的问题来添加所有说明。还要包括您解决问题的尝试
0赞 Demetris Demetriou 3/30/2023
@CBroe 你能详细说明一下你的意思吗?我尝试在变量 $clDays[]=$day(它显示在注释的代码上)中分配返回的数组,以获取从数据库循环数组后找到的日期,但我仍然无法让它工作,因为我仍然需要在 foreach 循环中。

答:

-2赞 zodiax 3/30/2023 #1

您可以使用 DISTINCT 方法:

$sqlClosedDays   = "SELECT DISTINCT Day FROM check_availability WHERE Blocked ='1'"; 

或者你可以使用 GROUP BY 方法:

$sqlClosedDays   = "SELECT Day FROM check_availability WHERE Blocked ='1' GROUP BY Day";     

评论

2赞 Nico Haase 3/30/2023
共享的示例数据不包含任何重复的行
0赞 Demetris Demetriou 3/31/2023 #2

由于@CBroe建议在循环之前和循环内部添加布尔标志,问题得到了解决。在我使用这些标志检查.我还添加了 Breaks 来停止循环。最后,我在代码的开头添加了对数据库的检查,如果存在任何关闭日。如果没有,它将根据 for 循环输出所有日期。这是工作代码。

 //SELECT START
  echo "<select name='add_r_date' id='add_r_date'>";
  for($i=0;$i<=30;$i++){
  //Get the Closed Days 
    //Display the Days according to limit   
  $day=date('l,d M',strtotime("+$i day"));
  $Nday = date('l',strtotime("+$i day"));
  $NdayTrim= substr($Nday, 0, 3);
  $InsDay = date('Y-m-d',strtotime("+$i day")); 
  $counter = 0;
  //CHECK IF THERE ARE ANY CLOSED/BLOCKED DAYS
  if(count($DaysClosed ) != 0 ){
  $clDays[] ='';  
  $isOpen = 'true';
    foreach ($DaysClosed as $rowDaysClosed) {   
        $dayClosed = $rowDaysClosed['Day'];
        $dayClosedTrim= substr($dayClosed, 0, 3);
        $dayTrim = substr($day, 0, 3);
        
            //If not Closed set as available
            if ($dayTrim === $dayClosedTrim ) { 
                $isOpen = 'false';
                echo "<option disabled value='$InsDay'>$day</option> ";     
                $clDays[] = $day;   
            } 
            $counter++;         
        }//EOF FOREACH LOOP 
    
    $total_count=$counter;
        
        foreach ($clDays as $rowclDays) {
            $daycl = $rowclDays;
            
    if($daycl === $day && $total_count > 0) 
    {
    //    echo "<option disabled value='$InsDay'>$day</option> ";
            $isOpen = 'false';
    break;
    }
        else if($isOpen == 'true') {    
     echo "<option name='add_r_date' id='add_r_date' value='$InsDay'>$day</option>";
            break;
            } 
        }//EOF 2nd FOREACH 

    //IF there arent any closing days
    } else {    

echo "<option name='add_r_date' id='add_r_date' value='$InsDay'>$day</option>";
    
    }       
    }//EOF for loop     

    echo "</select>";