我用“”将数据保存在我的数据库(mysql)中serialize($array);
。此数据来自带有输入字段的表单。我想知道如果我a:4:{i:1;s:7:"fdsfdsf";i
在表单字段中插入类似“”的内容会发生什么。会破坏我存储在数据库中的数据吗?谢谢!!
3 回答
我在我的系统上测试了您的示例,序列化后,返回以下值:
string(42) "a:1:{i:0;s:24:"a:4:{i:1;s:7:"fdsfdsf";i";}"
这就是将添加到数据库中的内容。但是,非常不鼓励在数据库中存储用户输入。您应该首先格式化普通用户输入,mysql_real_escape_string()
因为它会转义关键字符。
除此之外,如果unserialize()
在从数据库读回的序列化文本上调用,则正确返回数组。它应该是安全的,但会产生意想不到的结果。
在数据库中存储序列化数组时要格外小心。序列化返回一个字符串,所以你存储数据的字段通常是VARCHAR
or TEXT
。如果你只是用一个新的数组覆盖存储的数组,旧的数据将完全丢失。要更新数据库,请确保首先将数据库中的数据读入数组,然后更新它,然后再将其写回数据库。
虽然不被禁止,但使用和存储在数据库中序列化的东西通常会产生很多问题。数据库有很多默认已知的数据类型,大的序列化数组会产生开销并使执行复杂化,如果以后需要修改系统,这简直就是一个麻烦。而且您不能对序列化字段使用关系查询。
老办法
当您仍在使用时mysql_
,您可以编写如下查询:
$sql = sprintf("INSERT INTO mytable (a) VALUES ('%s')",
mysql_real_escape_string(serialize($myvar))
);
mysql_query($sql) or die("oh no!");
推荐的方式
PDO
并且您mysqli
可以选择使用准备好的语句,强烈建议您这样做,以防止 SQL 注入攻击向量。PDO 中的一个例子:
$stmt = $db->prepare('INSERT INTO mytable (a) VALUES (:myvar)');
$stmt->execute(array(
':myvar' => serialize($myvar),
));
字段长度
另外,确保序列化数据的长度不超过表字段的列大小;截断的序列化变量几乎没有用。
阻止这种情况的一种方法是在将数据插入数据库之前转义引号。
你可以用http://www.php.net/manual/en/mysqli.real-escape-string.php做到这一点mysqli_real_escape_string()