Почему фабричный метод 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 документация, которая гласит:

Замечания:

Когда объект уничтожен, его хэш может быть повторно использован для других объектов.

Так что это не странное поведение.

Другие вопросы по тегам