我做了一些测试,下面是我笔记(希望这将是可以理解的^^ ;;而我并没有太迷失在我自己的想法^^)
注:我已经对PHP 5.3.2-dev进行了测试,以防万一。
首先,让我们定义一个temp-2.php
文件,那将只包含此:
<?php
class a {
}
即对应于我们试图反序列化对象的类的定义。
而我将发布的所有其他代码部分将包含在名为temp.php
的文件中 - 这将包括temp-2.php
,因此该类的定义是已知的。
首先尝试:我们尝试反序列化的字符串,而不必定义的类a
:
$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';
function callback_spl($className) {
var_dump(__FUNCTION__ . ' : ' . $className);
}
spl_autoload_register('callback_spl');
$data = unserialize($serialized_object);
var_dump($data);
作为输出,我们得到这样的:
string 'callback_spl : a' (length=16)
object(__PHP_Incomplete_Class)[1]
public '__PHP_Incomplete_Class_Name' => string 'a' (length=1)
public 'value' => string '100' (length=3)
这意味着, :
- 自动加载功能
callback_spl
被称为
- 即使抢注
spl_autoload_register
- 但一直没有自动加载的东西
- 而且,作为类不被自动加载,我们得到了一个对象,它是一个的
__PHP_Incomplete_Class
现在例子,让我们尝试使用spl_autoload_register
注册,实际上自动加载的类的定义的自动加载功能:
$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';
function callback_spl($className) {
var_dump(__FUNCTION__ . ' : ' . $className);
require dirname(__FILE__) . '/temp-2.php';
}
spl_autoload_register('callback_spl');
$data = unserialize($serialized_object);
var_dump($data);
我们得到这个输出中:
string 'callback_spl : a' (length=16)
object(a)[1]
public 'value' => string '100' (length=3)
这意味着:
- 通过
spl_autoload_register
注册的自动加载功能有被称为
- 将未序列化已经成功的定义文件
- 即我们没有得到的
__PHP_Incomplete_Class
了一个实例,
- 我们实际上得到的的
a
例如所以,在这里,我要说的是unserialize_callback_func
不neede d当使用spl_autoload_register
时。
我想,在这里,我有种回答这个问题?但我会后一对夫妇的其他测试,只是为了好玩^^
现在,如果我们尝试使用unserialize_callback_func
,而不是使用spl_autoload_register
什么?
代码看起来像他,我想:
$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';
ini_set('unserialize_callback_func', 'callback_no_spl');
function callback_no_spl($className) {
var_dump(__FUNCTION__ . ' : ' . $className);
require dirname(__FILE__) . '/temp-2.php';
}
$data = unserialize($serialized_object);
var_dump($data);
而且,作为输出,我们得到:
string 'callback_no_spl : a' (length=19)
object(a)[1]
public 'value' => string '100' (length=3)
所以,一切正常OK:
- 的
callback_no_spl
回调函数通过unserialize_callback_func
注册被称为
- 的定义和数据正确地去系列化
一个实例去更远一些,让我们试着我们可以得到什么时候:
- 设置的自动加载功能,称为
callback_no_spl
,与unserialize_callback_func
- 并设置另一个自动加载功能,称为
callback_spl
,与spl_autoload_register
的代码看起来就像这样:
$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';
ini_set('unserialize_callback_func', 'callback_no_spl');
function callback_no_spl($className) {
var_dump(__FUNCTION__ . ' : ' . $className);
require dirname(__FILE__) . '/temp-2.php';
}
spl_autoload_register('callback_spl');
function callback_spl($className) {
var_dump(__FUNCTION__ . ' : ' . $className);
require dirname(__FILE__) . '/temp-2.php';
}
$data = unserialize($serialized_object);
var_dump($data);
和输出我们得到:
string 'callback_spl : a' (length=16)
object(a)[1]
public 'value' => string '100' (length=3)
其中意思是:
- 只有
spl_autoload_register
注册的自动加载函数被调用
- 它没有加载包含类的定义
- 而且数据已经被正确去系列化的文件。
现在,只是为了好玩,如果我们试图改变中,我们设置的自动加载机的顺序?
即使用此代码部分:
$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';
spl_autoload_register('callback_spl');
function callback_spl($className) {
var_dump(__FUNCTION__ . ' : ' . $className);
require dirname(__FILE__) . '/temp-2.php';
}
ini_set('unserialize_callback_func', 'callback_no_spl');
function callback_no_spl($className) {
var_dump(__FUNCTION__ . ' : ' . $className);
require dirname(__FILE__) . '/temp-2.php';
}
$data = unserialize($serialized_object);
var_dump($data);
我们得到完全相同的输出前:
string 'callback_spl : a' (length=16)
object(a)[1]
public 'value' => string '100' (length=3)
这似乎表明,自动装载机,spl_autoload_register
定义为比定义的一个更高的优先级与unserialize_callback_func
。
我还能测试什么?
哦,让我们来测试同时设置自动加载的功能,但拥有spl_autoload_register
(即具有最高优先级)注册的一个不实际加载类的定义:
$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';
ini_set('unserialize_callback_func', 'callback_no_spl');
function callback_no_spl($className) {
var_dump(__FUNCTION__ . ' : ' . $className);
require dirname(__FILE__) . '/temp-2.php';
}
spl_autoload_register('callback_spl');
function callback_spl($className) {
var_dump(__FUNCTION__ . ' : ' . $className);
//require dirname(__FILE__) . '/temp-2.php'; // We don't load the class' definition
}
$data = unserialize($serialized_object);
var_dump($data);
这个时候,这里的输出中我们得到:
string 'callback_spl : a' (length=16)
string 'callback_no_spl : a' (length=19)
object(a)[1]
public 'value' => string '100' (length=3)
基本上是:
- 自动加载函数的n,其中
spl_autoload_register
注册已被称为
- 因此,与
unserialize_callback_func
注册的自动加载函数被调用
- 它没有加载类的定义
- 因此,我们已经正确地获得了未序列化的数据。
现在,让我们回过头来您发布的代码示例 - 转换为我函数的名称,它会给我们这样的事情,我想:
$serialized_object='O:1:"a":1:{s:5:"value";s:3:"100";}';
ini_set('unserialize_callback_func', 'callback_no_spl');
function callback_no_spl($className) {
var_dump(__FUNCTION__ . ' : ' . $className);
//require dirname(__FILE__) . '/temp-2.php'; // We don't load the class' definition
}
spl_autoload_register('callback_spl');
function callback_spl($className) {
var_dump(__FUNCTION__ . ' : ' . $className);
//require dirname(__FILE__) . '/temp-2.php'; // We don't load the class' definition
}
$data = unserialize($serialized_object);
var_dump($data);
而且,这一次,我得到了和你一样的东西:
string 'callback_spl : a' (length=16)
string 'callback_no_spl : a' (length=19)
string 'callback_spl : a' (length=16)
(!) Warning: unserialize() [function.unserialize]: Function callback_no_spl() hasn't defined the class it was called for ...
object(__PHP_Incomplete_Class)[1]
public '__PHP_Incomplete_Class_Name' => string 'a' (length=1)
public 'value' => string '100' (length=3)
而且,这一次:
- 与
spl_autoload_register
注册的函数被调用
- 然后,
unserialize_callback_func
注册的函数被调用
- 和魔术一样,用
spl_autoload_register
注册的功能再次被调用!
- 和繁荣,我们得到一个警告说,与
unserialize_callback_func
注册功能没有加载类的定义
- 注意这只发生在
callback_spl
第二次被调用!
- 这似乎表明,即使用
unserialize_callback_func
定义的函数没有加载应该有的内容,也会发生某种自动加载。
我不得不承认,这是两个很好的和有难度的 - 和我有相当不知道为什么发生这种情况,因为似乎没什么道理不...
我想这奇怪行为是与事实,这样做:
的“栈/队列”的spl_autoload_register
的行为,我想,可以有一些干扰与unserialize_callback_func
旧的行为...
您是否有机会通过查看symfony代码来提出这个问题? – VolkerK 2010-02-24 13:42:40
是的!我正在检查symfony代码,以便知道它是如何工作的!它源自sfCoreAutoload.class.php中的'register'方法。 – user198729 2010-02-24 13:49:26