PHP出現Notice: unserialize() [function.unserialize]: Error at offset問題的解決方案 阿星小棧

 

今天的用PHP的時候無意的出現了用unserialize()函數轉換老是返回false,我確認我的字符串是沒錯的,測試了很多次還是一樣,沒辦法,啓用了error_reporting(E_ALL)啓用錯誤信息,沒想到發現了Notice: unserialize() [function.unserialize]: Error at offset的信息, 因爲我字符我是從數組轉換過來的,所以應該是沒有錯的, Google了一下,原來是編碼問題,在PHP手冊的評論中有人討論了此問題.

原來我的字符串是從數據庫裏取出來的,而原來插入數據庫時我的PHP用的是ANSCII編輯,而我複製出來後用unserialize()的PHP文件是UTF-8編碼,編碼不同,所以就出現錯誤了.

例子:
“ 首頁以ANSCII方式操作

<?php

$arr = array('en' => 'hello', 'cn' => '您好');
$str = serialize($arr);
echo $str;

?>

輸出結果: a:2:{s:2:"en";s:5:"hello";s:2:"cn";s:4:"您好";}

然後以UTF-8的編碼方式來測試

則以上代碼的輸出結果爲: a:2:{s:2:"en";s:5:"hello";s:2:"cn";s:6:"您好";}




看到有什麼不同了吧,在出現中文字符時字符長度就不一樣了,也就是strlen('您好')在第一種編碼中是4,而在第二種編碼中是6,其中原因可以查看相關手冊. 而unsrialize()要根據類似 s:6:"您好" 中的6來判斷字符長度並進行反序列,但原來的是4,字符長度不符,也就是出現了offset錯誤

解決辦法:
“ 將要反序列的字符串進行一次轉換,代碼

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

或者用自己自定的函數來代替unserialize

function mb_unserialize($serial_str) {
$out = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str );
return unserialize($out);
}


PHP比較麻煩的非屬編碼問題不可了,我們在處理字符問題的時候,很多函數都要我們自己進行自定義重寫,所以不是統一編碼的好一點.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章