php unserialize bool(false),php unserialize 返回false的解決方法

php unserialize 返回false的解決方法

php 提供serialize(序列化) 與unserialize(反序列化)方法。

使用serialize序列化后,再使用unserialize反序列化就可以獲取原來的數據。

$arr = array(

'name' => 'fdipzone',

'gender' => 'male'

);

$str = serialize($arr); //序列化

echo 'serialize str:'.$str."\r\n\r\n";

$content = unserialize($str); // 反序列化

echo "unserialize str:\r\n";

var_dump($content);

?>

輸出:

serialize str:a:2:{s:4:"name";s:8:"fdipzone";s:6:"gender";s:4:"male";}

unserialize str:

array(2) {

["name"]=>

string(8) "fdipzone"

["gender"]=>

string(4) "male"

}

但下面這個例子反序列化會返回false

$str = 'a:9:{s:4:"time";i:1405306402;s:4:"name";s:6:"新晨";s:5:"url";s:1:"-";s:4:"word";s:1:"-";s:5:"rpage";s:29:"http://www.baidu.com/test.html";s:5:"cpage";s:1:"-";s:2:"ip";s:15:"117.151.180.150";s:7:"ip_city";s:31:"中國北京市 北京市移動";s:4:"miao";s:1:"5";}';

var_dump(unserialize($str)); // bool(false)

?>

檢查序列化后的字符串,發現出問題是在兩處地方

s:5:"url"

s:29:"http://www.baidu.com/test.html"

這兩處應為

s:3:"url"

s:30:"http://www.baidu.com/test.html"

出現這種問題的原因是序列化數據時的編碼與反序列化時的編碼不一致導致,例如數據庫是latin1和UTF-8字符長度不一樣。

另外有可能出問題的還有單雙引號,ascii字符"\0"被解析為 '\0',\0在C中是字符串的結束符等於chr(0),錯誤解析后算了2個字符。

\r在計算長度時也會出問題。

解決方法如下:

// utf8

function mb_unserialize($serial_str) {

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

$serial_str= str_replace("\r", "", $serial_str);

return unserialize($serial_str);

}

// ascii

function asc_unserialize($serial_str) {

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

$serial_str= str_replace("\r", "", $serial_str);

return unserialize($serial_str);

}

例子:

echo '';

// utf8

function mb_unserialize($serial_str) {

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

$serial_str= str_replace("\r", "", $serial_str);

return unserialize($serial_str);

}

$str = 'a:9:{s:4:"time";i:1405306402;s:4:"name";s:6:"新晨";s:5:"url";s:1:"-";s:4:"word";s:1:"-";s:5:"rpage";s:29:"http://www.baidu.com/test.html";s:5:"cpage";s:1:"-";s:2:"ip";s:15:"117.151.180.150";s:7:"ip_city";s:31:"中國北京市 北京市移動";s:4:"miao";s:1:"5";}';

var_dump(unserialize($str)); // false

var_dump(mb_unserialize($str)); // 正確

使用處理過單雙引號,過濾\r的mb_unserialize方法就能成功反序列化了。

使用unserialize

bool(false)

使用mb_unserialize

array(9) {

["time"]=>

int(1405306402)

["name"]=>

string(6) "新晨"

["url"]=>

string(1) "-"

["word"]=>

string(1) "-"

["rpage"]=>

string(30) "http://www.baidu.com/test.html"

["cpage"]=>

string(1) "-"

["ip"]=>

string(15) "117.151.180.150"

["ip_city"]=>

string(31) "中國北京市 北京市移動"

["miao"]=>

string(1) "5"

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值