【问题标题】:"Foreach + if" only works for the last element"Foreach + if" 仅适用于最后一个元素
【发布时间】:2017-07-16 11:34:32
【问题描述】:

上下文:

我有一个带有复选框的表单和一个 php 页面来处理数据。我检查了我的数据:一切正常。

为了管理复选框,我做了一个“FOREACH”,根据表单中选中的框,在其中找到了几个带有指令和 sql 查询的“IF”循环。

我尝试循环我的数组以输入适合用户选中的每个框的循环“IF”。

问题:

当我运行脚本时,我检查了 3 或 5 个框,只考虑了最后一个循环“IF”... :(

我检查了表单 HTML 和 PHP 测试 POST:一切正常。

所以我的问题是:

我在哪里搞砸了,以至于 foreach 只会在“IF”循环中传递数组的最后一个元素?

代码如下:

if ( isset($_POST['ModalMultipleColorEdit']) && !empty($_POST['Planning_ID2']) && !empty($_POST['CaseColor2']) && !empty($_POST['CaseWeek2']) )
{  
    //------- Extract Needed Posted Data
    $TargetID = $_POST['Planning_ID2'];
    $TargetColor = $_POST['CaseColor2'];
    $TargetMonth = $_POST['CaseMonth2'];


   //----- GET OLD DATA
   $REQ = $DB->query("SELECT * FROM `Planning` WHERE `ID_Planning` =  ".$TargetID." ;")
   or die(var_dump($REQ->errorInfo()));
   $DATA = $REQ->fetch();



   // Explore Targeted Weeks Array
   foreach( $_POST['CaseWeek2'] as $CheckedWeek )
   {
        //----------- IF TARGET MONTH IS JANUARY   
       if ( $TargetMonth == "Janvier"  && $CheckedWeek == "(S-1)" )
       {           
              //------- Extract Color String Period
              $GetColor = explode("." , $DATA['Planning_M1']);

              //------- Change Period Color
              $GetColor[0] = $TargetColor;

              //------- Build New Color String
              $NewCaseMonth = $GetColor[0].".".$GetColor[1].".".$GetColor[2].".".$GetColor[3].".".$GetColor[4];

             // ------ UPDATE REQUEST
             $REQ2 = $DB->prepare('UPDATE `Planning` SET Planning_M1 = ? WHERE `ID_Planning` = ?');                        
             $REQ2->execute(array($NewCaseMonth, $TargetID)) or die(var_dump($REQ2->errorInfo()));
             $REQ2 = NULL;        
       }


       if ( $TargetMonth == "Janvier"  && $CheckedWeek == "(S-2)" )
       {      
             //------- Extract Color String Period
             $GetColor = explode("." , $DATA['Planning_M1']);

             //------- Change Period Color
             $GetColor[1] = $TargetColor;

            //------- Build New Color String
            $NewCaseMonth = $GetColor[0].".".$GetColor[1].".".$GetColor[2].".".$GetColor[3].".".$GetColor[4];

            // ------ UPDATE REQUEST
            $REQ2 = $DB->prepare('UPDATE `Planning` SET Planning_M1 = ? WHERE `ID_Planning` = ?');
            $REQ2->execute(array($NewCaseMonth, $TargetID)) or die(var_dump($REQ2->errorInfo()));
            $REQ2 = NULL;     
        }


       if ( $TargetMonth == "Janvier"  && $CheckedWeek == "(S-3)" )
       {          
            //------- Extract Color String Period
            $GetColor = explode("." , $DATA['Planning_M1']);

            //------- Change Period Color
            $GetColor[2] = $TargetColor;

            //------- Build New Color String
            $NewCaseMonth = $GetColor[0].".".$GetColor[1].".".$GetColor[2].".".$GetColor[3].".".$GetColor[4];


            // ------ UPDATE REQUEST
            $REQ2 = $DB->prepare('UPDATE `Planning` SET Planning_M1 = ? WHERE `ID_Planning` = ?');

            $REQ2->execute(array($NewCaseMonth, $TargetID)) or die(var_dump($REQ2->errorInfo()));
            $REQ2 = NULL; 
       }


       if ( $TargetMonth == "Janvier"  && $CheckedWeek == "(S-4)" )
       {      
            //------- Extract Color String Period
            $GetColor = explode("." , $DATA['Planning_M1']);

            //------- Change Period Color
            $GetColor[3] = $TargetColor;

            //------- Build New Color String
            $NewCaseMonth = $GetColor[0].".".$GetColor[1].".".$GetColor[2].".".$GetColor[3].".".$GetColor[4];

            // ------ UPDATE REQUEST
            $REQ2 = $DB->prepare('UPDATE `Planning` SET Planning_M1 = ? WHERE `ID_Planning` = ?');                     
            $REQ2->execute(array($NewCaseMonth, $TargetID)) or die(var_dump($REQ2->errorInfo()));
            $REQ2 = NULL;     
       }


       if ( $TargetMonth == "Janvier"  && $CheckedWeek == "(S-5)" )
       {
             //------- Extract Color String Period
            $GetColor = explode("." , $DATA['Planning_M1']);

            //------- Change Period Color
            $GetColor[4] = $TargetColor;

            //------- Build New Color String
            $NewCaseMonth = $GetColor[0].".".$GetColor[1].".".$GetColor[2].".".$GetColor[3].".".$GetColor[4];

            // ------ UPDATE REQUEST
            $REQ2 = $DB->prepare('UPDATE `Planning` SET Planning_M1 = ? WHERE `ID_Planning` = ?');                         
            $REQ2->execute(array($NewCaseMonth, $TargetID)) or die(var_dump($REQ2->errorInfo()));
            $REQ2 = NULL; 
       }
   }


   //------- REDIRECT WHEN SUCCESS AND NO MORE TARGETS
   header('Location: PlanningNow.php?Process=Success');
   exit();

}




else
{
   header('Location: PlanningNow.php?Process=ErrorForm');
   exit();
}

提前感谢您的帮助! :)

【问题讨论】:

  • 在您的逻辑中看起来像问题。您正在更新最后一个元素,因为每次在循环中,您以前的值都会更新为最新值,所以最后您将获得最后更新的值
  • 这就是我的想法......但我不知道如何解决它?有什么建议吗?
  • 什么是自增数组?
  • 那才叫索引数组
  • 是的,我需要做的是在每次迭代中执行查询...你认为我需要创建一个自动递增数组还是索引数组?

标签: php if-statement foreach


【解决方案1】:

我不得不编造一些数据进行测试。考虑使用这种方法将查询调用减少到一个,并在很大程度上整合您的代码...

代码:(Demo)

$_POST['CaseWeek2']=['(S-2)','(S-3)','(S-5)']; // target checkboxes
$_POST['CaseColor2']='purple';  // target color
$_POST['CaseMonth2']='Janvier'; // target month

$checkedWeeks=['(S-1)','(S-2)','(S-3)','(S-4)','(S-5)'];  // possible checkboxes

$DATA['Planning_M1']='red.orange.yellow.green.blue';  // old data from db
$oldcolors=explode('.',$DATA['Planning_M1']);

if($_POST['CaseMonth2']=='Janvier'){
    // var_export(array_intersect($checkedWeeks,$_POST['CaseWeek2']));
    $keys=array_keys(array_intersect($checkedWeeks,$_POST['CaseWeek2'])); // get appropriate keys
    // var_export($keys);
    $values=array_fill(0,sizeof($keys),$_POST['CaseColor2']);  // generate equal number of values
    // var_export($values);
    $replacements=array_combine($keys,$values);  // combine keys and values to make correct array
    // var_export($replacements);
    $newcolors=array_replace($oldcolors,$replacements);  // replace old values with new values
    var_export($newcolors);
    //$REQ2=$DB->prepare('UPDATE `Planning` SET Planning_M1 = ? WHERE `ID_Planning` = ?');                        
    //$REQ2->execute(array(implode('.',$newcolors), $TargetID));    
}

输出:

array (
  0 => 'red',
  1 => 'purple',
  2 => 'purple',
  3 => 'green',
  4 => 'purple',
)

哦,郑重声明,您之前的迭代被“忽略”的原因是:

$GetColor = explode("." , $DATA['Planning_M1']);

每次调用 UPDATE 时,您实际上是在拉取旧的缓存 $DATA['Planning_M1'] 数据,以单一颜色交换,并覆盖早期迭代的 UPDATE。



如果你想保持你的代码基本相同,你可以这样写:

$GetColor = explode("." , $DATA['Planning_M1']);

foreach() 循环之前,然后有条件地修改$GetColor,就像您当前对$GetColor[n] 所做的那样。然后在循环结束后,您可以使用完全修改的$GetColor 数据对数据库进行一次 UPDATE 调用。

【讨论】:

  • 哦,是的!你是对的,现在我明白了,它就像魅力一样!非常感谢 ! ;)