【问题标题】:Json_encode/decode in phpphp 中的 Json_encode/decode
【发布时间】:2012-11-09 20:39:39
【问题描述】:

我在视图 $all_set 上有一个数组,其中包含一些 id。现在我想使用表单提交在控制器中传递这个数组。因为我使用了 j 儿子编码和解码。

在我看来:

<?php $all_set=json_encode($all_set); ?>

<input type="hidden" name="all_set" value="<?php echo serialize($all_set); ?>">

上面的值包含(正如我在页面源代码中看到的):

<input type="hidden" name="all_set" value="s:26:"{"0":"1","5":"2","13":"3"}";">

现在在控制器上:

$result=$this->input->post('all_set');

           $result= unserialize($result);
           $result=json_decode($result);
           print_r($result); die;

这给了我错误,我没有在控制器上得到任何数组。 错误:

Message: unserialize() [function.unserialize]: Error at offset 0 of 5 bytes

为什么会这样?请帮忙。

【问题讨论】:

  • 为什么要序列化 ​​JSON 文本?
  • 实际上我是第一次使用 json 将数据发送到控制器,但 webnetmobile.com 给了我答案。

标签: php json codeigniter serialization


【解决方案1】:

您必须将htmlspecialchars() 添加到您的序列化中。

<input type="hidden" name="all_set" value="<?php echo htmlspecialchars(serialize($all_set)); ?>">

编辑

为什么这能解决问题?让我们先看看 OP 的引用输出:

value="s:26:"{"0":"1","5":"2","13":"3"}";">
      ^     ^

我添加了^ 来标记问题来源 - 你的值包含引号,这使得浏览器看到这个输入时更像这样:

value="s:26:" {"0" "1" , "5" : "2","13":"3"}";">

一旦找到匹配的",它就会简单地关闭字符串。 HTML 中有一些特殊字符,包括&lt;&gt;&amp;",如果希望它们按字面传递,则必须将其转换为实体。所以通过调用htmlspecialchars(),我们转换了所有这些字符,标记看起来像这样:

value="s:26:&quot;{&quot;0&quot;:&quot;1&quot;,&quot;5&quot;.....

浏览器现在可以正确解释、正确显示并正确发回,但不将其视为标记的一部分。

编辑 2

事实上,反序列化在您的代码中非常有用。完全摆脱serialize()/unserialize() - 你的json编码数据只是纯字符串,所以你只需要htmlspecialchars()

【讨论】:

  • 你能告诉我为什么我们必须添加 htmlspecialchars() 吗??
  • 请查看 R S 的答案。使用 unserialize() 会使您面临安全漏洞。
  • awesome..gr8 解释..gr8 帮助..+1 解释
  • @JonathanAmend R.S.提供与使用序列化相同级别的安全性。来自用户的任何数据都不可信。如果您构建一个表单并将您的 数据放入隐藏字段,然后用户提交该表单,那么那里就没有更多的您的数据。它用户数据。它是所有用户数据。而且您必须再次验证它 - 绝对您首先将它放在那里没有任何区别。这是 any 客户端/服务器代码中的经验法则。问题是关于在表单中使用序列化数据的问题,而不是关于如何假装理解安全问题。
  • @WebnetMobile.com 如果您让他们继续对从用户接收到的数据使用 unserialize(),您只会把他们带下悬崖。 base64_decode() 没有执行任意代码的风险,而 unserialize() 有。你不妨让他 eval() 它。
【解决方案2】:

试试

<input type="hidden" name="all_set" value="<?php echo base64_encode($all_set); ?>">

$result= base64_decode($result);
$result=json_decode($result);

【讨论】:

  • 虽然这也行得通,但这并不是一个完全正确的解决方案,因为您是在解决问题,而不是消除真正的罪魁祸首。
  • @WebnetMobile.com 这不是真的。 R S 在取消使用 unserialize() 方面是正确的。如果您要对从用户端提供的数据进行反序列化,那么您将面临一个相当大的安全漏洞,因为传回脚本的数据可以被操纵以使您的服务器执行攻击者希望的任何 PHP 代码: heine.familiedeelstra.com/security/unserialize
  • 没有来自用户的数据是可信的。这就是为什么您总是进行服务器端验证的原因。如果您认为 base64 是针对这种情况的任何形式的保护,那么您就错过了重点。
猜你喜欢
  • 2012-07-28
  • 1970-01-01
  • 2015-01-19
  • 2011-09-04
  • 2011-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多