Я сделал несколько тестов, и здесь ноты, которые я взял (надеюсь, это будет понятно ^^ ;; и что я не получил слишком потерял в моей собственной мысли ^^)
Примечание: Я провел тесты на 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)
Итак, все работает ОК:
- Функция
callback_no_spl
обратного вызова зарегистрированный через unserialize_callback_func
, называется
- Он загружает определение класса
- И данные десериализации правильно
- т.е. мы получаем экземпляр
a
Забегая дальше, давайте попробуем что мы можем получить, когда оба:
- Установка функции автозагрузки, называемая
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);
На этот раз, вот Ouput мы получаем:
string 'callback_spl : a' (length=16)
string 'callback_no_spl : a' (length=19)
object(a)[1]
public 'value' => string '100' (length=3)
В основном:
- самозарядные ФУНКЦИИ п зарегистрирован
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
Да, я просматриваю код symfony, чтобы узнать, как он работает точно. Он получен из метода 'register' в sfCoreAutoload.class.php – user198729