如何通过隐藏字段传递数组

22

这是我的代码

$order[$j][0]="Euclidean Geomethiyil Kodpagugal";
$order[$j][1]=$q16;
$j++;

隐藏域

<input type="hidden" name="hdnTotal" value="<?php echo $gtot; ?>">
<input type="hidden" name="hdnOrder" value="<?php echo $order; ?>">
<input type="submit" value="Place Order">

hdnTotal的值可以在下一页中获取,但是hdnOrder无法获取。当使用print($_POST['hdnOrder'])时,只会在屏幕上打印出Array


这是因为order是一个数组,而不是一个特定的值。 - Alex
4
你曾想过使用“会话(session)”吗? - Gumbo
为什么这个不被接受? - Baba
7个回答

45
你可以将数组序列化,或使用大量隐藏字段。另外,也可以将其存储在会话中。
序列化数组
为了进行序列化,只需使用一个隐藏字段即可。如果数组包含非标量数据,则这是一种有用的技术。
 $data=serialize($order); 
 $encoded=htmlentities($data);
 echo '<input type="hidden" name="order" value="'.$encoded.'">';

当这个值返回时,您需要反序列化它才能将数组取回。虽然很容易,但我不建议这样做,除非您有一些额外的机制来防止篡改,比如安全哈希,否则任何人都可以注入他们喜欢的PHP数据结构!
哈希可能会像这样完成:
 $data=serialize($order); 
 $encoded=htmlentities($data);
 $hash=md5($encoded.'SecretStringHere');
 echo '<input type="hidden" name="order" value="'.$encoded.'">';
 echo '<input type="hidden" name="order_hash" value="'.$hash.'">';

现在,在数据反序列化之前,生成哈希值并检查它是否与表单中的哈希值匹配。如果不匹配,则有人篡改了数据。如果匹配,则您知道生成数据的任何内容也知道您的秘密字符串。这应该只是你自己!
最后,如果JavaScript需要理解数组数据,那么使用PHP的JSON encode/decode函数会更合适。
多个隐藏字段
假设一个由标量值组成的简单数组,您可以使用许多隐藏字段。
 foreach($order as $idx=>$value)
 {
      $name=htmlentities('order['.$idx.']');
      $value=htmlentities($val);
      echo '<input type="hidden" name="'.$name.'" value="'.$value.'">';

 }

这样做的好处是PHP会自动将其重新创建为数组

由于您的数组是二维的,要使用这种技术,您需要为第二个维度使用内部循环。留给读者的练习....

使用会话

也许这三种方法中最简单的一种....

session_start();

$_SESSION['order']=$order;

一旦设置,只要调用session_start(),该数组就可以使用。这样做的好处是它永远不会离开服务器,但当空闲时间超过一定期限(默认为24分钟)后,当然也会消失。


我不理解你的解决方案:使用它在客户端操作数据将会非常困难,那么为什么不发送它而不是保留在客户端? - Pascal Qyy
1
OP似乎不需要任何客户端操作,只需在表单提交后保留数据。但是,如果确实需要客户端操作,则JSON会更合适,正如我在答案中所指出的那样。 - Paul Dixon
那么,如果既不是为了处理数据,也不是为了显示数据,为什么要将数据发送给客户端再由客户端重新发送给服务器呢? - Pascal Qyy

11

将序列化到单个字段的替代方案是将其序列化为多个隐藏字段。我编写了一个通用函数来执行此操作。此函数和示例正在GistHub的Gist服务上管理。请前往那里查看最新版本,但为了方便,也复制在这里。

<?php
# https://gist.github.com/eric1234/5802030

function array_to_input($array, $prefix='') {
  if( (bool)count(array_filter(array_keys($array), 'is_string')) ) {
    foreach($array as $key => $value) {
      if( empty($prefix) ) {
        $name = $key;
      } else {
        $name = $prefix.'['.$key.']';
      }
      if( is_array($value) ) {
        array_to_input($value, $name);
      } else { ?>
        <input type="hidden" value="<?php echo $value ?>" name="<?php echo $name?>">
      <?php }
    }
  } else {
    foreach($array as $item) {
      if( is_array($item) ) {
        array_to_input($item, $prefix.'[]');
      } else { ?>
        <input type="hidden" name="<?php echo $prefix ?>[]" value="<?php echo $item ?>">
      <?php }
    }
  }
}

以下是一些示例用法:

基本关联数组

echo array_to_input(array('foo' => 'bar', 'cat' => 'dog'));

将输出:

<input type="hidden" value="bar" name="foo">
<input type="hidden" value="dog" name="cat">

嵌套索引数组的关联数组

echo array_to_input(array('foo' => 'bar', 'cat' => 'dog', 'list' => array('a', 'b', 'c')));

将输出:

<input type="hidden" value="bar" name="foo">
<input type="hidden" value="dog" name="cat">
<input type="hidden" name="list[]" value="a">
<input type="hidden" name="list[]" value="b">
<input type="hidden" name="list[]" value="c">

嵌套关联数组

echo array_to_input(array('foo' => array('bar' => 'baz', 'a' => 'b'), 'cat' => 'dog'));

将输出:

<input type="hidden" value="baz" name="foo[bar]">
<input type="hidden" value="b" name="foo[a]">
<input type="hidden" value="dog" name="cat">

疯狂起来

echo array_to_input(array('a' => array('b' => array('c' => array('d' => 'e')))));

将输出:

<input type="hidden" value="e" name="a[b][c][d]">

9

尝试使用 json_encode

<input type="hidden" name="hdnTotal" value="<?php echo htmlspecialchars(json_encode($gtot)); ?>">
<input type="hidden" name="hdnOrder" value="<?php echo htmlspecialchars(json_encode($order)); ?>">
<input type="submit" value="Place Order">

并且要获取它,json_decode

print(json_decode($_POST['hdnOrder']));

这种解决方案的优点在于,您可以轻松地使用JavaScript在客户端上操作数组。
但是,为什么要这样做呢?
如果不是为了在客户端上操作数据,那么您会产生不必要的数据往返,而您可以轻松地使用PHP sessions将其保留在服务器端。

如果你不使用JavaScript,就没有理由使用JSON;PHP有自己的序列化格式。这些函数在许多网络主机仍在使用的PHP 5.1.x或更早版本中不可用。你也不能直接将JSON插入HTML中,因为它包含双引号、空行和其他需要编码的字符。 - Dan Grossman
1
正如我所说,使用 JSon,可以在客户端使用 Javascript 操纵数据。PHP 序列化不能做到这一点,如果客户端只是将数据原样发送回来,那么为什么要将数据发送到客户端呢? - Pascal Qyy

5
如果您有非标量值,应该对它们进行序列化和反序列化。您有多个选项:
  1. PHP的serializeunserialize
  2. JSONencodedecode
一般规则是,如果您将任何值放入HTML中,您需要编码其HTML特殊字符。
用例:
<?php
$arr = unserialize($_REQUEST['arr']);
?>
<input type="hidden" name="arr" value="<?php echo htmlentities(serialize($arr)); ?>" />

2
这个表单要去哪里,为什么需要将多维数组作为表单的一部分进行传递?
如何实现这一点取决于您是否控制接收表单的页面。如果是您控制该页面,则有几个选项:
1)使用PHP的serialize函数将数组序列化为字符串,然后使用unserialize $_POST ['order'] 来获取原始数组。
2)通过生成的表单字段数组进行传递。
<input type="hidden" name="hdnOrder[0][0]" value="Something" />
<input type="hidden" name="hdnOrder[0][1]" value="Something else" />

如果您没有控制表单,则您提交的内容可能期望hdnOrder中有特定内容...那是什么?

为什么当你建议使用JSON编码而不是PHP自己的序列化时,我的解决方案很糟糕? - Dan Grossman

0

对于 Java Servlets

arr={"Apple","Bannana","Cherry","Dragan"};
for(int i=0;i<4;i++)
    out.println("<input type=hidden name=fruits value="+arr[i]+">");

这里展示了一个数组值的例子,可以使用以下语句从另一个页面获取数组值。String arr[] = req.getParameterValues("trees"); - Murali N
请编辑您的答案以添加更多信息。在评论中很容易被忽略。 - David Buck

-1
听起来你只是想从表单的一个页面传递数据到另一个页面。如果是这样,可以使用 PHP 会话(Session)。它更容易实现,更高效,也更安全。

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