Почему фабричный метод Pimple возвращает тот же экземпляр?
Я использую фабричный метод Pimple, но он каждый раз возвращает один и тот же экземпляр.
$container = new \Pimple\Container();
echo '<pre>';
$container['test'] = $container->factory(function( $c ) {
$services = new \Pimple\Container();
return $services;
} );
// Both outputs string(32) "0000000061066681000000005c9b6294"
var_dump( spl_object_hash( $container['test'] ) );
var_dump( spl_object_hash( $container['test'] ) );
Это точное поведение, которого я не ожидаю, учитывая определение метода, говорящего, что он каждый раз дает новый экземпляр.
Я нахожусь на PHP 7.0.4, и мой файл композитора для прыща отмечен в ^3.0.0
1 ответ
Pimple не возвращает тот же экземпляр, но по какой-то известной причине эти хеши точно такие же. Это не то, что связано с Pimple, а связано с spl_object_hash и тем, как PHP обрабатывает объекты внутри. Цитируя это примечание, внесенное пользователем, часть, которая отвечает на ваш вопрос, выделена жирным шрифтом:
Обратите внимание, что содержимое (свойства) объекта НЕ хешируется функцией, просто ее внутренний дескриптор и указатель таблицы обработчика. Этого достаточно, чтобы гарантировать, что любые два объекта, одновременно находящиеся в памяти, будут иметь разные хэши. Уникальность не гарантируется между объектами, которые не находились в памяти одновременно, например:
var_dump (spl_object_hash (новый stdClass()), spl_object_hash(новый stdClass ()));
Выполнение этого одного обычно генерирует те же хеши, так как PHP повторно использует внутренний дескриптор для первого stdClass после того, как он был разыменован и уничтожен, когда он создает второй stdClass.
Так что это потому, что вы не сохраняете ссылку на возвращаемые объекты. Вы просто создаете их, печатаете их хеши, а затем PHP выбрасывает их из памяти. Для лучшего понимания этой заметки попробуйте сохранить эти экземпляры в памяти, назначив их переменным ($ref1
а также $ref2
Вот):
$container = new \Pimple\Container();
$container['test'] = $container->factory(function( $c ) {
$services = new \Pimple\Container();
return $services;
} );
// Outputs different object hashes
print( spl_object_hash( $ref1 = $container['test'] ) );
print "\n";
print( spl_object_hash( $ref2 = $container['test'] ) );
print "\n";
Есть также примечание в spl_object_hash
документация, которая гласит:
Замечания:
Когда объект уничтожен, его хэш может быть повторно использован для других объектов.
Так что это не странное поведение.