2012-05-31 78 views
5

我使用“serialize($ array);”将数据保存在我的数据库(mysql)中。这些数据来自带有输入字段的表单。我想知道如果我在表单字段中插入“a:4:{i:1; s:7:”fdsfdsf“; i”)会发生什么情况。可以打破我存储在数据库中的数据? 谢谢!Php序列化Mysql中的数据

回答

9

我测试了我的系统上的例子做到这一点,序列化之后,将返回以下值:

string(42) "a:1:{i:0;s:24:"a:4:{i:1;s:7:"fdsfdsf";i";}" 

这是将被添加到数据库中。但是,非常不鼓励将用户输入存储在数据库中。您应该首先使用mysql_real_escape_string()格式化纯用户输入,因为它会转义重要字符。

除此之外,如果在从数据库读回的序列化文本上调用unserialize(),则会正确返回该数组。它应该是安全的,但会产生意想不到的结果。

非常小心将序列化数组存储在数据库中。序列化返回一个字符串,所以你存储数据的字段通常是VARCHAR或TEXT。如果你只是用覆盖存储的数组,旧数据将会完全丢失。若要更新数据库,请确保您首先将数据从数据库读取到数组中,并更新它,然后才将其写回数据库。

虽然它不被禁止,但是在数据库中使用和存储被串行化的东西通常会产生很多问题。数据库有很多默认情况下已知的数据类型,而大型序列化数组会造成开销并使执行复杂化,如果稍后需要修改系统,那么这只是一个麻烦。并且您不能在序列化字段上使用关系查询。

+0

感谢您的回复和建议,一直非常有帮助! – alejoabella

+2

由于php序列化数据返回二进制数据,请不要使用VARCHAR或TEXT,而应使用VARBINARY或BLOB。 –

6

旧的方式

当你还在使用mysql_你可以写这样的疑问:

$sql = sprintf("INSERT INTO mytable (a) VALUES ('%s')", 
    mysql_real_escape_string(serialize($myvar)) 
); 
mysql_query($sql) or die("oh no!"); 

推荐的方法

PDOmysqli你得到的可以选择使用准备好的语句,强烈推荐这些语句用于防止SQ L注入攻击矢量。在PDO的一个例子:

$stmt = $db->prepare('INSERT INTO mytable (a) VALUES (:myvar)'); 
$stmt->execute(array(
    ':myvar' => serialize($myvar), 
)); 

字段长度

此外,请确保您的序列化的数据不超过表中的字段的列大小的长度;截断的序列化变量几乎没用。

+1

@alejoabella不客气。回到这个答案,我意识到这并不是那么好,所以我修改了它:) –

+0

呃......准备好的语句又如何防止注入?确切地说 - 他们不。完全一样。 – specializt

+1

@specializt准备好的陈述在这方面并不神奇,人们仍然可以(并且确实)搞砸了,最近的[Drupal咨询](https://www.drupal.org/SA-CORE-2014- 005)。但是,如果您认为我的答案中的陈述可以被利用,请告诉我该如何实现。 –