Unserialize与Autoload

但凡是一个合格的PHP程序员,就应该知道Unserialize与Autoload,但是要说起二者之间的关系,恐怕一清二楚的人就不多了。

说个例子,假设我们可以拿到第三方的序列化数据,但没有相应的类定义,代码如下:

<?php

$string = 'O:6:"Foobar":2:{s:3:"foo";s:1:"1";s:3:"bar";s:1:"2";}';

$result = unserialize($string);

var_dump($result);

/*

object(__PHP_Incomplete_Class)[1]
  public '__PHP_Incomplete_Class_Name' => string 'Foobar' (length=6)
  public 'foo' => string '1' (length=1)
  public 'bar' => string '2' (length=1)

*/

?>

当我们反序列化一个对象时,如果对象的类定义不存在,那么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:6:"Foobar":2:{s:3:"foo";s:1:"1";s:3:"bar";s:1:"2";}';

$result = (array)unserialize($string);

var_dump($result);

/*

array
  '__PHP_Incomplete_Class_Name' => string 'Foobar' (length=6)
  'foo' => string '1' (length=1)
  'bar' => string '2' (length=1)

*/

?>

不过如果系统激活了Autoload,情况会变得复杂些。顺便插句话:PHP其实提供了一个名为unserialize_callback_func配置选项,但意思和autoload差不多,这里就不介绍了,咱们就说autoload,例子如下:

<?php

spl_autoload_register(function($name) {
    var_dump($name);
});

$string = 'O:6:"Foobar":2:{s:3:"foo";s:1:"1";s:3:"bar";s:1:"2";}';

$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:6:"Foobar":2:{s:3:"foo";s:1:"1";s:3:"bar";s:1:"2";}';

$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:6:"Foobar":2:{s:3:"foo";s:1:"1";s:3:"bar";s:1:"2";}';

$result = (array)unserialize($string);

var_dump($result);

?>

不得不说,上面的代码真的很狗屎!那怎么做才好呢?我大致写了一个实现:

<?php

spl_autoload_register(function($name) {
    include "/path/to/{$name}.php";
});

$string = 'O:6:"Foobar":2:{s:3:"foo";s:1:"1";s:3:"bar";s:1:"2";}';

$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类,看上去舒服多了。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索对象
, 代码
, 一个
, autoload
, _autoload
, unserialize
, __autoload
, unserialize()
, spl_autoload_register
__autoload()
unserialize、php unserialize、unserialize 在线、unserialize 失败、php unserialize 在线,以便于您获取更多的相关知识。

时间: 2025-01-21 10:53:15

Unserialize与Autoload的相关文章

PHP基础之Autoload

PHP的自动加载autoload机制很重要,这里做2个小练习   原创文章,转载请注明:http://www.cnblogs.com/phpgcs   文件结构如下,2种方式实现自动加载   1,自定义函数   2,spl_autoload_register()     liuyuan@ebuinfo:/var/www/phpgcs/php_autoload$ ll ./* -rw-rw-r-- 1 liuyuan liuyuan  800 Feb 19 11:39 ./func_autoloa

php反序列unserialize的一个小特性

这几天wordpress的那个反序列漏洞比较火,具体漏洞我就不做分析了,看这篇吧http://drops.wooyun.org/papers/596,你也可以去看英文的原文http://vagosec.org/2013/09/wordpress-php-object-injection/. wp官网打了补丁,我试图去bypass补丁,但让我自以为成功的时候,发现我天真了,并没有成功绕过wp的补丁,但却发现了unserialize的一个小特性,在此和大家分享一下.   1.unserialize(

JavaScript 版本的 PHP serialize/unserialize 完整实现

javascript 以前写 PHPRPC 实现时,JavaScript 版本的序列化实现是修改自 http://www.devpro.it/code/102.html 的,这个实现虽然目前仍然在更新,不过它并没有完全实现 PHP 序列化的所有标记,因此它无法序列化复杂对象,例如嵌套对象,也无法反序列化所有的 PHP 序列化以后的内容.因此我重新编写了一个实现,这个实现与 PHP 5 的序列化完全兼容,并且可以反序列化 PHP 4.PHP 5 和 PHP 6 序列化的内容.支持魔术方法 __sl

php autoload:解决 PHP 中的

        最近,在项目中发现,PHP 的 __autoload 方法失效了.调试了好久,百思不得其解,查了下资料才知道原来是 Smarty 的原因.新版的 Smarty 改变了autoload的方式.        解决方法是:在 Smarty 的包含类文件后加一段代码,spl_autoload_register("__autoload");        如下:<?phpdefine('ROOT_PATH', dirname(__FILE__));require_once

PHP autoload与include性能比较

自PHP5后,官方大大丰富了对面向对象的支持,其中有个重要改变:引入了__autoload()函数,从此不再需要在php脚本的header写一堆的require或include了,用PHP函数手册中的话说:"它会在试图使用尚未被定义的类时自动调用". 这一机制大大减轻了开发人员的负担,只要在架构初期考虑好了目录结构和命名规范,在开发过程中,需要再为代码中要用到的类分别去require相应的文件,减少了大量代码. 但这样一来,也容易出现运行一个程序,某个类文件被include多次,例如有

如何解决php unserialize返回false的问题

php unserialize 返回false的解决方法 php 提供serialize(序列化) 与unserialize(反序列化)方法. 使用serialize序列化后,再使用unserialize反序列化就可以获取原来的数据. <?php $arr = array( 'name' => 'fdipzone', 'gender' => 'male' ); $str = serialize($arr); //序列化 echo 'serialize str:'.$str."\

Ext2.0升级至Ext2.1 Ext.Panel的AJAX加载方式autoLoad参数使用的变化

Ext2.0.2升级到2.1了,开发也要与时俱进嘛.虽说这直接替换了2.0.2,但是却遇到一个不大不小的麻烦.ExtJs Panel的远程页面加载是一个非常好的功能,之前的有些调用代码在2.1却无法显示最新的数据了. API DOC 如是说: Ext.Panel.autoLoad A valid url spec according to the Updater Ext.Updater.update method. If autoLoad is not null, the panel will

关于unserialize的问题

特的理念.', 'uid' => 1, 'nickname' => '土豆男', 'site' => ", 'sitetype' => 1, 'starttime' => 1191074174, 'lasttime' => 1191629784, 'totleviews' => 14, 'totleblogs' => 3 ); 由于程序自动判断了magic_quotes_gpc并将所有POST,GET的数据自动转义(addslashes下),所以上

php序列化函数serialize() 和 unserialize() 与原生函数对比

  这篇文章主要介绍了php序列化函数serialize() 和 unserialize() 与php原生序列化方法对比,有需要的小伙伴可以参考下. php中有格式化字符串并转换成数组或对象的好方法,即序列化处理. 有两种序列化变量的方法. 以下示例,使用 serialize() 和 unserialize() 函数: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32