Whenever a qualified PHP programmer, you should know Unserialize and autoload, but to talk about the relationship between the two, I am afraid that there are not many people.
For example, suppose that we can get a third party serialization data, but there is no corresponding class definition, the code is as follows:
<?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)
* *
?>
When we deserialize an object, if the object's class definition does not exist, then PHP introduces the concept of an unfinished class, namely: __php_incomplete_class, at this point, although we deserialized successfully, but still can not access the data in the object, the following error message will appear:
The script tried to execute a or access a is incomplete object. Please ensure this class definition of the object you are trying to operate on is loaded _before_ () unserialize Called or provide a __autoload () function to load the class definition.
It's not a hard thing to do, just do a mandatory type conversion and become an array 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) c8/> ' Bar ' => string ' 2 ' (length=1)
* *
?>
But if the system activates the autoload, the situation can become more complicated. By the way: PHP actually provides a name for the UNSERIALIZE_CALLBACK_FUNC configuration option, but meaning and autoload almost, here is not introduced, we will say autoload, examples are as follows:
<?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);
? >
Executing the above code will find that Spl_autoload_register is triggered, most of the time it makes sense, but if you encounter a poorly defined spl_autoload_register, it will be sad, such as the following code:
<?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);
? >
No doubt, because the class definition file could not be found, so the error! Change Spl_autoload_register Affirmation line, but the premise is you can change, if involves the third party code, we can not take the decision without authorization, at this time we need a way to let Unserialize can bypass AutoLoad, The easiest way to do this is to fake the class we need:
<?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);
? >
I have to say, the code above is really very dog-poo! What's the best way to do that? I have roughly written an implementation:
<?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);
? >
The code is a bit more, but at least there is no fake class, it looks more comfortable.