【问题标题】:how to pass array through hidden field如何通过隐藏字段传递数组
【发布时间】:2010-11-21 08:50:40
【问题描述】:

这是我的代码

$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 是一个数组,而不是一个具体的值。
  • 你有没有想过使用会话?
  • 为什么不被接受???

标签: php arrays hidden


【解决方案1】:

您可以序列化数组,也可以使用大量隐藏字段。或者,将其存储在会话中。

序列化数组

对于serialize,您将只使用一个隐藏字段。如果您的数组包含非标量数据,这是一种有用的技术。

 $data=serialize($order); 
 $encoded=htmlentities($data);
 echo '<input type="hidden" name="order" value="'.$encoded.'">';

当该值返回时,您需要unserialize 以将您的数组恢复。虽然很简单,但我不建议这样做,除非你有一些额外的机制来防止篡改,比如安全哈希,否则任何人都可以注入他们喜欢的任何 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会为你automatically recreate this as an array

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

使用会话

也许是三个中最简单的一个......

session_start();

$_SESSION['order']=$order;

一旦设置,数组在您调用 session_start() 后可用。这样做的好处是它永远不会离开服务器,但当然会在一段时间不活动后消失(默认为 24​​ 分钟)

【讨论】:

  • 我不明白你的解决方案:用它在客户端操作数据将非常困难,那么发送它而不是将其保留在客户端呢?
  • OP 似乎不需要任何客户端操作,只是为了保存表单帖子中的数据。但是,如果需要客户端操作,那么 JSON 会更合适,如我的回答中所述。
  • 那么为什么要发送数据给客户端只是为了他重新发送到服务器,如果它既不处理也不显示呢?
【解决方案2】:

序列化到单个字段的另一种解决方案是序列化到多个隐藏字段。我写了一个通用函数来做到这一点。此功能和示例在GistHub's Gist service 进行管理。在此处查看最新版本,但为方便起见,请在此处复制。

<?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]">

【讨论】:

    【解决方案3】:

    试试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 或更早版本中不可用,许多 Web 主机仍在使用。您也不能像这样将 JSON 直接粘贴到 HTML 中,因为它包含双引号、空行和其他需要编码的字符。
    • 正如我所说,使用 JSon,可以使用 Javascript 在客户端操作数据。 PHP 序列化不可能做到这一点,如果客户端只是按原样发送数据,为什么还要向客户端发送数据?
    【解决方案4】:

    如果你有非标量值,你应该序列化和反序列化它们。您有多种选择:

    1. PHP 的 serializeunserialize
    2. JSON encodedecode

    作为一般规则,如果您在 HTML 中输入任何值,您需要 encode 其 HTML 特殊字符。

    用例:

    <?php
    $arr = unserialize($_REQUEST['arr']);
    ?>
    <input type="hidden" name="arr" value="<?php echo htmlentities(serialize($arr)); ?>" />
    

    【讨论】:

      【解决方案5】:

      这个表单要去哪里,为什么需要一个多维数组作为表单的一部分传递?

      您将如何执行此操作取决于您是否控制接收表单的页面。如果你这样做了,你有几个选择:

      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 自己的序列化之外,为什么当你提出相同的解决方案时我的解决方案很糟糕?
      【解决方案6】:

      对于 java servlet

      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");
      • edit您的回答添加更多信息。在 cmets 中迷路的可能性要大得多。
      【解决方案7】:

      您只是想将数据从表单的一个页面传递到另一个页面。如果是这样,请使用 PHP 会话。它更容易实施、更高效、更安全。

      【讨论】:

        猜你喜欢
        • 2011-11-02
        • 1970-01-01
        • 2011-07-07
        • 2016-01-31
        • 1970-01-01
        • 1970-01-01
        • 2020-11-16
        • 2017-02-25
        • 1970-01-01
        相关资源
        最近更新 更多