PHP:数组 $_POST 循环问题

3
我要询问一个关于我遇到的问题的问题,并尝试根据你们的输入来解决这个问题。如果我真的无法解决它,我会发布源代码,但是在此之前...
所以,我有一个表单,它垂直显示字段。所有内容都是下拉菜单,在最后是提交按钮。有一点javascript可以让我在不刷新页面的情况下添加新行。因此,每个键的$_POST数组的数量都不相同。我担心的关键(其实是所有的,但是一旦我弄好了,所有的都可以工作)是$_POST['monworkhours']下拉菜单。这是一个具有不同工作时间列表的下拉菜单。我认为问题在于我需要根据提交循环遍历所有的$_POST ['monworkhours']数组。我不太清楚如何做到这一点。
另外,“问题”会导致输出的每一行都产生相同的结果。因此,我设置的第一个字段将成为通过javascript函数“添加”的每个附加行的结果。
感谢任何帮助。
表格:
<select name="monshifthours[]" id="monshifthours">
        <option value="OFF">OFF</option>
    <optgroup label="Front/Back Half">
        <option value="7am7pm">7AM-7PM</option>
        <option value="7pm7am">7PM-7AM</option>           
        <option value="7am7pmalt">7AM-7PM (Alt)</option>
        <option value="7pm7amalt">7PM-7AM (Alt)</option>
    </optgroup>
    <optgroup label="Monday - Friday">
        <option value="630am330pm">630AM-330PM</option>
        <option value="7am4pm">7AM-4PM</option>
        <option value="8am5pm">8AM-5PM</option>
        <option value="10am7pm">10AM-7PM</option>
    </optgroup>
  </select>

$_POST输出(2个表单行):

 ["monshifthours"]=>
  array(2) {
    [0]=>
    string(6) "7am7pm"
    [1]=>
    string(6) "7pm7am"
  }

截图: 在此输入图片描述 getCellColor()函数:
function getCellColor($dow) {
      foreach($_POST[$dow . 'shifthours'] as $key=> $hour) {
          echo $count;
          if ($hour == "7am7pmalt") {
              return "style=\"background: yellow; color:#000;\"";
          }
          elseif ($hour == "OFF") {
              return    "style=\"background: red; color:#fff;\"";
          }
          else {
              return "style=\"background: green; color:#fff;\"";
          }
    }
}

提交输出:

if (isset($_POST['submit'])) {
    echo preTableFrmt();
    foreach($engineer as $a => $b) {
        echo "| [[$engineer[$a]]] || ".getCellColor('mon')." | $monday[$a] || ".getCellColor('tues')." | $tuesday[$a] || ".getCellColor('wed')." | $wednesday[$a] || ".getCellColor('thur')." | $thursday[$a] || ".getCellColor('fri')." | $friday[$a] || ".getCellColor('sat')." | $saturday[$a] || ".getCellColor('sun')." | $sunday[$a] <br />|-<br />";
    }
    echo postTableFrmt();
}
else { echo "Waiting for data..."; }

注意:当提交一个表单行时,一切都很好;但当我有多个表单行时,就会出现重复信息的问题。
下面的示例应该能展示当我"添加一个工程师"(使其现在有两个表单行)时会发生什么。我将在图片之后发布输出结果:
应用程序截图: enter image description here 注意:不要关注时间的输出,因为它们是通过一些正则表达式即时格式化的,其中一些有效,而另一些则不是,因为我还需要完成编写这些函数。请注意,我发送的以下输出在第一部分是正确的,但第二部分是第一行输出的重复。
|-
| [[Drew Decker]] || style="background: yellow; color:#000;" | 7am7pmalt || style="background: red; color:#fff;" | OFF || style="background: red; color:#fff;" | OFF || style="background: red; color:#fff;" | OFF ||  |  || style="background: red; color:#fff;" | OFF || style="background: red; color:#fff;" | OFF 
|-
| [[Drew Decker]] || style="background: yellow; color:#000;" | 7pm-7am || style="background: red; color:#fff;" | OFF || style="background: red; color:#fff;" | OFF || style="background: red; color:#fff;" | OFF ||  |  || style="background: red; color:#fff;" | OFF || style="background: red; color:#fff;" | OFF 

注意:这里的重复项是 style="background: yellow; color:#000;"我的解决方案
所以,我最终找到了一个解决方案,它不需要我改变表单代码。我认为我不需要改变表单代码,因为它是动态的。通常,在将多行表单数据提交到数据库时,我可以看到这很重要,但在这种情况下,我不认为这是正确的解决方案。不过,我非常感谢所有有深思熟虑和信息丰富的答案。
我最终将 getCellColor() 函数更改为以下内容:
function getCellColor($index,$dow) {
        if ( isset($_POST[$dow . 'shifthours'][$index]) && ($_POST[$dow . 'shifthours'][$index] == "7am7pmalt" || $_POST[$dow . 'shifthours'][$index] == "7pm7amalt")) {
            return "style=\"background: yellow; color:#000;\"";
        }
        elseif ($_POST[$dow . 'shifthours'][$index] == "OFF") {
            return  "style=\"background: red; color:#fff;\"";
        }
        else {
            return "style=\"background: green; color:#fff;\"";
        }
}

我现在的foreach看起来像这样:

foreach($engineer as $a => $b) {
    echo "|-<br />| [[$engineer[$a]]] || ".getCellColor($a,"mon")." | ".format_date($monday[$a])." || ".getCellColor($a,"tues")." | ".format_date($tuesday[$a])." || ".getCellColor($a,"wed")." | ".format_date($wednesday[$a])." || ".getCellColor($a,"thur")." | ".format_date($thursday[$a])." || ".getCellColor($a,"fri")." | ".format_date($friday[$a])." || ".getCellColor($a,"sat")." | ".format_date($saturday[$a])." || ".getCellColor($a,"sun")." | ".format_date($sunday[$a])."<br />";
}

以这种方式操作可以确保我只需要告诉它选择正确的数组索引,然后相应地进行处理。

你能展示一行数据吗?(字段名称对于解决此问题很有趣) - Dr.Molle
天啊,我忘记添加额外的信息了-很抱歉;它很快就会出现。 - drewrockshard
4个回答

1
以下的解决方案适用于具有相同名称的复选框列表。我认为它也适用于下拉菜单列表,正如我下面所写的那样,但我还没有测试过。
<select name="monworkhours[]">
    <option value="aaa">aaa</option>
    <option value="bbb">bbb</option>
    <option value="ccc">ccc</option>
</select>

<select name="monworkhours[]">
    <option value="ddd">ddd</option>
    <option value="eee">eee</option>
    <option value="fff">fff</option>
</select>

一旦您提交此表单,$_POST ['monworkhours'] 有望成为一个数组。我还没有测试过它,但我不认为这会有问题。

这已经是我的设置了。循环遍历它们并逐个输出信息是问题所在。 - drewrockshard
我不是很理解你的问题,但是你知道一旦提交表单后,只有下拉列表中你选择的选项才会列在你的 $_POST 变量中,对吧?换句话说,所有选项都不会被发布,只有你选择的那个。 - Mauro
请阅读我的初始帖子。我有一些JavaScript代码,可以动态创建新行。这些新行是相同的表单,因此我可以插入相同事物(针对不同人)的多个值。这意味着我永远不会知道我将有2个$_POST ['monworkhours']还是100个;这完全取决于用户。 - drewrockshard

1

遍历 $_POST['monworkhours'] 是微不足道的:

foreach ($_POST['monworkhours'] as $i => $value){
    // Do something
}

没有看到更多的代码,我无法确定你的问题在哪里。你是在HTML中选择值(例如<option value="7am7pm" selected>7AM-7PM</option>),还是使用javascript?

如果是javascript,可能与您对多个元素使用相同的ID有关。这在技术上是不正确的。您可以使用连续编号的ID,如下所示:

<select name="monshifthours_0" id="monshifthours_0">
...
<select name="monshifthours_1" id="monshifthours_1">

然后在PHP中迭代它们,就像这样:

$i = 0;
while (isset($_POST["monshifthours_$i"])){
    // Do something
    $i++;
}

如果以上方法均无法解决问题,请贴出更多的代码。越多越好。

1

我想现在我明白了你的问题。你的问题是,一旦你提交表单,这段代码就会运行:

foreach($engineer as $a => $b) {             
    echo "| [[$engineer[$a]]] || ".getCellColor('mon')." | ...";
}  

换句话说,对于每个工程师,您都要运行函数getCellColor();

现在,函数getCellColor()也会完成循环并评估所有发布的项目,因此返回您最后一个表单行的结果。

function getCellColor($dow) {
    foreach($_POST[$dow . 'shifthours'] as $key=> $hour) {   
    ...
    }
}

换句话说,这里正在发生什么:

  • 启动foreach(engineer)循环
  • foreach(engineer)获取工程师1
  • 在工程师1内部,getCellColor开始运行
  • getCellColor评估每一行并返回最后一行的值
  • foreach(engineer)循环并获取工程师2
  • 在工程师2内部,getCellColor开始运行
  • getCellColor评估每一行并返回最后一行的值(再次)
  • ......以此类推

注意:您说输出的第一行是正确的,但实际上不是。每行都输出最后一行的结果。

作为建议,我会像Patrick Fisher在他的答案中提到的那样来结构化事物。

<select name="aa_1"> <select name="bb_1"> <input type="hidden" name="lines[]" value="1" />
<select name="aa_2"> <select name="bb_2"> <input type="hidden" name="lines[]" value="2" />
<select name="aa_3"> <select name="bb_3"> <input type="hidden" name="lines[]" value="3" />

这样,一旦您提交表单,您可以逐个水平地获取每个表单元素(即逐行),而不是垂直地获取。

foreach($_POST["lines"] as $key => $value) { 
    ${"aa_".$value} = $_POST["aa_".$value];
    ${"bb_".$value} = $_POST["bb_".$value];
}

谢谢您分解这个逻辑。在您让我意识到我在代码中所做的事情后,我最终想出了自己的解决方案,我发现我只需要将索引作为参数添加到我的 getCellColor 函数中,它就可以正常工作了! :) - drewrockshard

1

所以,最终我找到了一个解决方案,不需要改变我的表单代码。我认为我不需要改变我的表单代码,因为它是动态的。通常,如果我将此写入数据库并将多行表单数据提交到数据库,则可以看出这很重要,但在这种情况下,我不认为这是正确的解决方案。无论如何,我感谢并赞赏我收到的所有周到和信息丰富的答案。

我最终将getCellColor()函数更改为以下内容:

function getCellColor($index,$dow) {
        if ( isset($_POST[$dow . 'shifthours'][$index]) && ($_POST[$dow . 'shifthours'][$index] == "7am7pmalt" || $_POST[$dow . 'shifthours'][$index] == "7pm7amalt")) {
            return "style=\"background: yellow; color:#000;\"";
        }
        elseif ($_POST[$dow . 'shifthours'][$index] == "OFF") {
            return  "style=\"background: red; color:#fff;\"";
        }
        else {
            return "style=\"background: green; color:#fff;\"";
        }
}

我的foreach现在看起来是这样的:

foreach($engineer as $a => $b) {
    echo "|-<br />| [[$engineer[$a]]] || ".getCellColor($a,"mon")." | ".format_date($monday[$a])." || ".getCellColor($a,"tues")." | ".format_date($tuesday[$a])." || ".getCellColor($a,"wed")." | ".format_date($wednesday[$a])." || ".getCellColor($a,"thur")." | ".format_date($thursday[$a])." || ".getCellColor($a,"fri")." | ".format_date($friday[$a])." || ".getCellColor($a,"sat")." | ".format_date($saturday[$a])." || ".getCellColor($a,"sun")." | ".format_date($sunday[$a])."<br />";
}

以这种方式做可以确保我只需要告诉它选择正确的数组索引,然后相应地继续进行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接