2010-03-30 22 views
5

Tôi có một trang web tôi muốn di chuyển từ ISO đến UTF-8.Chức năng PHP serialize có tương thích với UTF-8 không?

Tôi có một kỷ lục trong cơ sở dữ liệu lập chỉ mục của khóa chính sau đây:

s:22:"Informations générales"; 

Vấn đề là, bây giờ (với UTF-8), khi tôi sắp đặt từng chuỗi, tôi nhận được:

s:24:"Informations générales"; 

(lưu ý kích thước của chuỗi hiện là số byte, không phải là chuỗi dài)

Vì vậy, điều này không tương thích với các bản ghi trước đó không phải là utf8!

Tôi có làm gì sai không? Làm thế nào tôi có thể sửa lỗi này?

Cảm ơn

+1

@Col Shrapnel: Đó gọi là 'Pháp' và, vì vậy, không này lạ. – Boldewyn

+1

Anh ấy không đề cập đến ngôn ngữ. Anh ta đang sử dụng chuỗi PHP được tuần tự hóa làm khóa chính. Điều đó lạ thật. –

+1

@Boldewyn, có lẽ anh ta không nói đến tiếng Pháp. – pars

Trả lời

2

Hành vi hoàn toàn chính xác. Hai chuỗi với các mã hóa khác nhau sẽ tạo ra các luồng byte khác nhau, do đó các chuỗi tuần tự khác nhau.

+0

Ok vì vậy điều này là bình thường: quá trình serialization cần chiều dài bộ nhớ, không phải chiều dài chuỗi –

+0

@Matthieu: Tôi biết điều này nghe có vẻ lạ, nhưng trong chuỗi PHP thực sự là mảng byte. Bạn sẽ nhận được kết quả tương tự nếu bạn 'echo strlen ($ utf8EncodedString)'. Đối với độ dài * ký tự *, bạn cần 'mb_strlen()'. – soulmerge

+0

Một số khác: 'file_get_contents()' sẽ cung cấp cho bạn một chuỗi (ngay cả khi nhận được nội dung của các tệp nhị phân). Chức năng Socket cũng vậy. – soulmerge

2

PHP 4 và 5 không có hỗ trợ Unicode tích hợp; Tôi tin rằng PHP 6 đang bắt đầu bổ sung thêm hỗ trợ Unicode mặc dù tôi không chắc nó hoàn toàn như thế nào.

+0

Tôi biết rằng, tôi chỉ muốn biết về tình trạng "khóa chính" –

0

Bạn không làm gì sai. PHP trước khi v6 không phải là Unicode nhận thức, và như vậy không hỗ trợ nó, nếu bạn không đánh bại nó được (tức là, thông qua phần mở rộng mbstring hoặc các phương tiện khác).

Chúng tôi ở đây đã viết trình bao bọc riêng của chúng tôi xung quanh serialize() để khắc phục điều này. Bạn cũng có thể chuyển sang các kỹ thuật tuần tự hóa khác, như JSON (với json_encode()json_decode() trong PHP từ 5.2.0).

3

Dump cơ sở dữ liệu trong latin1.

Trong dòng lệnh:

sed -e 's/latin1/utf8/g' -i ./DBNAME.sql 

nhập các tập tin chuyển đổi sang một cơ sở dữ liệu mới trong UTF-8.

Sử dụng tập lệnh php để cập nhật từng trường. Thực hiện một truy vấn, lặp qua từng lĩnh vực và cập nhật các chuỗi tuần tự sử dụng này:

$str = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $str); 

Sau đó, tôi đã có thể sử dụng unserialize() và tất cả mọi thứ làm việc với UTF-8.

+0

Vấn đề lớn với điều này là nếu chuỗi của bạn có dấu ngoặc kép trong đó chúng sẽ được đặt trước bằng dấu gạch chéo ngược vì PHP cố gắng giúp bạn (đây là một tác dụng phụ của cờ "e"). Sử dụng "preg_replace_callback" có vẻ là một cách tốt để giải quyết vấn đề này. –

1

Để unserialize một mảng serialized utf-8 mã hóa:

$array = @unserialize($arrayFromDatabase); 
if ($array === false) { 
    $array = @unserialize(utf8_decode($arrayFromDatabase)); //decode first 
    $array = array_map('utf8_encode', $array); // encode the array again 
} 
+0

Tôi thấy giải pháp này rất hữu ích khi bạn có dữ liệu tuần tự hóa được mã hóa trước trong ISO-8859-X và cần sử dụng nó trong một ứng dụng được chuyển đến UTF-8. –

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