2012-05-31 83 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)。但是,如果您認爲我的答案中的陳述可以被利用,請告訴我該如何實現。 –