2012-05-31 34 views
5

Tôi lưu dữ liệu trong db của tôi (mysql) với "serialize ($ array);". Dữ liệu này đến từ một biểu mẫu có trường nhập. Tôi muốn biết điều gì xảy ra nếu tôi chèn một cái gì đó như "a: 4: {i: 1; s: 7:" fdsfdsf "; i" trong trường biểu mẫu. có thể phá vỡ dữ liệu của tôi được lưu trữ trong DB? Cảm ơn !!Php Serialize dữ liệu trong Mysql

Trả lời

9

Tôi đã thử nghiệm ví dụ của bạn trên hệ thống của tôi, và sau khi serialization, giá trị sau đây được trả về:

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

Đây là những gì sẽ được bổ sung vào cơ sở dữ liệu. Tuy nhiên, lưu trữ đồng bằng đầu vào người dùng trong cơ sở dữ liệu là rất nản lòng. Trước tiên, bạn nên định dạng đầu vào người dùng đơn giản bằng mysql_real_escape_string() vì nó sẽ thoát khỏi các ký tự quan trọng.

Ngoài ra, nếu unserialize() được gọi trên văn bản được đọc lại từ cơ sở dữ liệu, mảng được trả về đúng cách. Nó phải an toàn, nhưng có thể tạo ra kết quả bất ngờ.

Hãy cực kỳ cẩn thận với việc lưu trữ các mảng được tuần tự hóa trong cơ sở dữ liệu. Serialization trả về một chuỗi, do đó, trường bạn lưu trữ dữ liệu trong thường là VARCHAR hoặc TEXT. Nếu bạn chỉ cần ghi đè mảng đã lưu bằng mảng mới, dữ liệu cũ sẽ bị mất hoàn toàn. Để cập nhật cơ sở dữ liệu, hãy đảm bảo bạn đọc dữ liệu đầu tiên từ cơ sở dữ liệu vào một mảng và cập nhật nó, sau đó chỉ ghi lại cơ sở dữ liệu.

Trong khi không bị cấm, việc sử dụng và lưu trữ nội dung được tuần tự hóa trong cơ sở dữ liệu thường tạo ra nhiều vấn đề. Cơ sở dữ liệu có rất nhiều kiểu dữ liệu được biết mặc định, và các mảng tuần tự hóa lớn tạo ra chi phí và thực thi phức tạp, và chỉ đơn giản là một nỗi đau trong ass nếu hệ thống sau này cần được sửa đổi. Và bạn không thể sử dụng các truy vấn quan hệ trên các trường được tuần tự hóa.

+0

Cảm ơn phản hồi và đề xuất của bạn, đã rất hữu ích !!! – alejoabella

+2

Khi dữ liệu tuần tự hóa php trả về dữ liệu nhị phân, không sử dụng VARCHAR hoặc TEXT mà là VARBINARY hoặc BLOB. –

6

Cách cũ

Khi bạn vẫn đang sử dụng mysql_ bạn có thể viết các truy vấn như thế này:

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

Cách đề nghị

Đối PDOmysqli bạn nhận được tùy chọn sử dụng các câu lệnh đã được chuẩn bị, được đề xuất rất cao cho chính xác mục đích ngăn ngừa SQ L tiêm tấn công vectơ. Một ví dụ trong PDO:

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

Dòng chiều dài

Ngoài ra, hãy chắc chắn rằng chiều dài của dữ liệu đăng của bạn không vượt quá kích thước cột của lĩnh vực bảng; một biến serialized cắt ngắn là khá nhiều vô dụng.

+1

@alejoabella Bạn được chào đón. Quay trở lại câu trả lời này, tôi nhận ra nó không phải là tuyệt vời sau khi tất cả, vì vậy tôi đã sửa đổi nó :) –

+0

um .... chính xác như thế nào báo cáo chuẩn bị ngăn ngừa tiêm, một lần nữa? Chính xác - họ không. Ở tất cả. – specializt

+1

@specializt Báo cáo chuẩn bị không phải là phép thuật trong khía cạnh đó, mọi người vẫn có thể (và làm) vặn nó lên, được chứng minh bởi [cố vấn Drupal] gần đây (https://www.drupal.org/SA-CORE-2014- 005). Tuy nhiên, nếu bạn cảm thấy rằng tuyên bố trong câu trả lời của tôi có thể được khai thác, hãy cho tôi biết làm thế nào điều này có thể đạt được. –

Các vấn đề liên quan