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

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

原來我serialize後的數組字符串是從數據庫裏取出來的,而原來插入數據庫時,因爲美工修改前臺視圖代碼時導致視圖編碼未保存成UTF8編碼而是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錯誤

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

$data=preg_replace('!s:(\d+):"(.*?)";!se',"'s:'.strlen('$2').':\"$2\";'",$data);
$data=unserialize($data);
如果您的解碼數組內容裏有類似(<img src=\"/new/uploadfile/editor/image/20131221/20131221201521_54813.jpg\" alt=\"\" />的雙引號轉移字符)的子元素,還需要對特定子元素去除重複的轉移雙引號(文本編輯器上傳圖片功能默認對URL內容進行了斜槓轉義,解碼後需要對其去除重複雙引號轉移)

a:7{s:8:"nickname";s:10:"4211931411";s:3:"uid";s:6:"481010";s:10:"other_type";s:1:"1";s:8:"other_id";i:2023;s:11:"other_title";s:143:"發佈了博文: <a href='/blog/a-log/uid-481010/id-2023' target='_blank'>中國有個你大爺 巧妙 答記者問 </a>";s:3:"des";s:232:"<p>
<img src=\"/new/uploadfile/editor/image/20131221/20131221201521_54813.jpg\" alt=\"\" /></p><p><p>1、記者:大爺,巿長被綁架了,綁匪要贖金一千萬,如果不給,他們就用汽油燒死他。現正在";s:11:"content_url";s:53:"/blog/a-log/uid-481010/id-2023";}

$data['des']=stripslashes($data['des']);


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