使用PHP通过POST提交多维数组

115

我有一个PHP表单,它有一定数量的列(例如顶部直径、底部直径、织物、颜色、数量等),但由于用户可以按需添加行,所以行数是未知的。

我已经找到了如何将每个字段(列)放入各自的数组中。

<input name="topdiameter['+current+']" type="text" id="topdiameter'+current+'" size="5" />
<input name="bottomdiameter['+current+']" type="text" id="bottomdiameter'+current+'" size="5" />

那么最终在HTML中得到的是:

<tr>
  <td><input name="topdiameter[0]" type="text" id="topdiameter0" size="5" /></td>
  <td><input name="bottomdiameter[0]" type="text" id="bottomdiameter0" size="5" /></td>
</tr>
<tr>
  <td><input name="topdiameter[1]" type="text" id="topdiameter1" size="5" /></td>
  <td><input name="bottomdiameter[1]" type="text" id="bottomdiameter1" size="5" /></td>
</tr>

...and so on.
我现在想做的是将所有行和列放入一个多维数组中,并将该内容通过电子邮件发送给客户(最好是以漂亮格式化的表格形式)。我一直无法真正理解如何将所有这些输入和选择组合成一个漂亮的数组。
此时,我将不得不尝试使用几个一维数组,尽管我有这样一个想法:使用单个二维数组比使用几个一维数组更好。
5个回答

166

提交后,您将获得一个类似于以下创建的数组:

$_POST['topdiameter'] = array( 'first value', 'second value' );
$_POST['bottomdiameter'] = array( 'first value', 'second value' );

不过,我建议将您的表单名称更改为以下格式:

name="diameters[0][top]"
name="diameters[0][bottom]"
name="diameters[1][top]"
name="diameters[1][bottom]"
...

使用这种格式,循环遍历值会更加容易。

if ( isset( $_POST['diameters'] ) )
{
    echo '<table>';
    foreach ( $_POST['diameters'] as $diam )
    {
        // here you have access to $diam['top'] and $diam['bottom']
        echo '<tr>';
        echo '  <td>', $diam['top'], '</td>';
        echo '  <td>', $diam['bottom'], '</td>';
        echo '</tr>';
    }
    echo '</table>';
}

谢谢!我已经接近实现了,尽管我把列和行搞反了。 - Fireflight
如果您正在克隆文本字段并且无法控制添加列表名称(例如name="diameters[0][top]),那么如果我有多个名称,例如顶部、底部、左侧和右侧,我该怎么办?@DisgruntledGoat - Maduro
@JMASTERB 晚来一步,但您需要使用JS添加一些处理,即如果它们是有序的,则在克隆后读取前一个输入名称,并手动逐个增加克隆中每个输入名称属性的值。 - Daniel
@disgruntledGoat,你能否做一个这个的jsfiddle吗? - jpgerb

24

你可以使用这样的命名方式提交所有参数:

params[0][topdiameter]
params[0][bottomdiameter]
params[1][topdiameter]
params[1][bottomdiameter]

然后稍后你会像这样做:

foreach ($_REQUEST['params'] as $item) {
    echo $item['topdiameter'];
    echo $item['bottomdiameter'];
}

4

我知道这是顶坟,但是我多年来遇到了同样的问题并且也一次又一次地得到了相同的答案。

今天,我又遇到了一个附加问题:我想让我的用户能够添加任意数量的条目,并在提交前重新排列他们的输入。因此,我想出了这个相对简单的解决方案:

$diameters = [];
foreach($_POST['diameters'] as $k=>$v){
 $val = intdiv($k,2);
 $diameters[$val][key($v)]=$v[key($v)];
}
$_POST['diameters']=$diameters;

硬编码的 2 是因为这是输入块(顶部直径,底部直径)的大小。
所以 HTML 可以简单地像这样:
<tr>
  <td><input name="diameters[][top]" type="text" [..] /></td>
  <td><input name="diameters[][bottom]" type="text" [..] /></td>
</tr>
<tr>
  <td><input name="diameters[][top]" type="text" [..] /></td>
  <td><input name="diameters[][bottom]" type="text" [..] /></td>
</tr>

这样,您最终将获得一个简单的数组,格式如下:
$_POST['diameters']=[
  ["top"=>"","bottom"=>""],
  ["top"=>"","bottom"=>""],
  ...
]

这将使您在处理数据时更加简单。

1
没有索引(数字)的直径[]在动态列表上运行良好,这些列表可能会有删除的行。而foreach是一个很好的工具,可以制作漂亮的有序数组。对于新手来说,注意intdiv()是为数组中每个主元素的2个子元素而设计的。如果需要更多,例如[top]、[bottom]、[right]、[left],则需要除以4。 - El Gucs
@Ant,你的代码对我的项目非常有帮助,用户也可以选择添加行并重新排序。但是,它更加复杂,因为在每一行中又有更多的行。例如:name="spaces[][walls][][orientation]"。我该如何编辑您的代码使其正常工作?非常感谢! - Senne Vandenputte
@SenneVandenputte 我不太确定您想如何重新排序和分组,但如果我是您,并且因为前端看起来非常复杂,我会添加一个前端js框架,至少像alpinejs或甚至jQuery这样的最小框架来处理数据,然后再通过js提交。 - Ant

1

@DisgruntledGoat的回答是完全正确的; 但是,如果有人正在寻找未设置为必需的值,意味着$_POST === null可能会发生,您将使用isset()条件,如下所示:

$placeHolderValue = "Incomplete";

if ( isset( $_POST['diameters'] ) )
{
    echo '<table>';
    foreach ( $_POST['diameters'] as $diam )
    {
        // here you have access to $diam['top'] and $diam['bottom']
        echo '<tr>';
        if (isset($diam['top'])) {
            echo '  <td>' . $diam['top'] . '</td>';
        } else {
            echo '<td>' . $placeHolderValue . '</td>';
        if (isset($diam['top'])) {
            echo '  <td>' . $diam['bottom'] . '</td>';
        } else {
            echo '<td>' . $placeHolderValue . '</td>';
        echo '</tr>';
    }
    echo '</table>';
}

这里所使用的命名格式是@DisgruntledGoat在他们的答案中提到的。

0
我创建了一个函数,可以处理数组以及单个的GET或POST值。
function subVal($varName, $default=NULL,$isArray=FALSE ){ // $isArray toggles between (multi)array or single mode

    $retVal = "";
    $retArray = array();

    if($isArray) {
        if(isset($_POST[$varName])) {
            foreach ( $_POST[$varName] as $var ) {  // multidimensional POST array elements
                $retArray[]=$var;
            }
        }
        $retVal=$retArray;
    }

    elseif (isset($_POST[$varName]) )  {  // simple POST array element
        $retVal = $_POST[$varName];
    }

    else {
        if (isset($_GET[$varName]) ) {
            $retVal = $_GET[$varName];    // simple GET array element
        }
        else {
            $retVal = $default;
        }
    }

    return $retVal;

}

例子:

$curr_topdiameter = subVal("topdiameter","",TRUE)[3];
$user_name = subVal("user_name","");

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