熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> PHP編程 >> 正文

Unserialize與Autoload

2022-06-13   來源: PHP編程 

    但凡是一個合格的PHP程序員就應該知道UnserializeAutoload但是要說起二者之間的關系恐怕一清二楚的人就不多了

  
說個例子假設我們可以拿到第三方的序列化數據但沒有相應的類定義代碼如下

  
<?php

  
$string = O“Foobar”{s“foo”ss“bar”s}

  
$result = unserialize($string)

  
var_dump($result)

  
/*

  
object(__PHP_Incomplete_Class)[]

  
public __PHP_Incomplete_Class_Name => string Foobar (length=)

  
public foo => string (length=)

  
public bar => string (length=)

  
*/

  
?>當我們反序列化一個對象時如果對象的類定義不存在那麼PHP會引入一個未完成類的概念__PHP_Incomplete_Class此時雖然我們反序列化成功了但還是無法訪問對象中的數據否則會出現如下報錯信息

  
The script tried to execute a method or access a property of an incomplete object Please ensure that the class definition of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition

  
這不是什麼難事兒只要做一次強制類型轉換變成數組就OK了

  
<?php

  
$string = O“Foobar”{s“foo”ss“bar”s}

  
$result = (array)unserialize($string)

  
var_dump($result)

  
/*

  
array

  
__PHP_Incomplete_Class_Name => string Foobar (length=)

  
foo => string (length=)

  
bar => string (length=)

  
*/

  
?>

    不過如果系統激活了Autoload情況會變得復雜些順便插句話PHP其實提供了一個名為unserialize_callback_func配置選項但意思和autoload差不多這裡就不介紹了咱們就說autoload例子如下

  
<?php

  
spl_autoload_register(function($name) {

  
var_dump($name)

  
})

  
$string = O“Foobar”{s“foo”ss“bar”s}

  
$result = (array)unserialize($string)

  
var_dump($result)

  
?>執行上面代碼會發現spl_autoload_register被觸發了多數時候這是有意義的但如果遇到一個定義不當的spl_autoload_register就悲催了比如說下面這段代碼

  
<?php

  
spl_autoload_register(function($name) {

  
include “/path/to/{$name}php”

  
})

  
$string = O“Foobar”{s“foo”ss“bar”s}

  
$result = (array)unserialize($string)

  
var_dump($result)

  
?>

    毫無疑問因為找不到類定義文件所以報錯 了!改改spl_autoload_register肯定行但前提是你能改如果涉及第三方代碼我們就不能擅自做主了此時我們需要一種方法讓 unserialize能繞開autoload最簡單的方法是把我們需要的類FAKE出來

  
<?php

  
spl_autoload_register(function($name) {

  
include “/path/to/{$name}php”

  
})

  
class Foobar {} // Oh Shit!

  
$string = O“Foobar”{s“foo”ss“bar”s}

  
$result = (array)unserialize($string)

  
var_dump($result)

  
?>不得不說上面的代碼真的很狗屎!那怎麼做才好呢?我大致寫了一個實現

  
<?php

  
spl_autoload_register(function($name) {

  
include “/path/to/{$name}php”

  
})

  
$string = O“Foobar”{s“foo”ss“bar”s}

  
$functions = spl_autoload_functions()

  
foreach ($functions as $function) {

  
spl_autoload_unregister($function)

  
}

  
$result = (array)unserialize($string)

  
foreach ($functions as $function) {

  
spl_autoload_register($function)

  
}

  
var_dump($result)

  
?>代碼雖然多了點但至少沒有FAKE類看上去舒服多了


From:http://tw.wingwit.com/Article/program/PHP/201311/21138.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.