Создать экземпляр объекта из кеша через класс в PHP - PullRequest
2 голосов
/ 15 апреля 2011

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

Лучше всего объяснить с помощью некоторого псевдокода:

$foo = new Foo('bar');
print $foo->eat_cpu_and_database_resources(); #=> 3.14159
$foo->store_in_cache(); #Uses an existing Memcached and/or caching to store serialized.

#new thread, such as a new HTTP request. Could be days later. 
$bar = new Foo('bar');
print $foo->eat_cpu_and_database_resources(); #=> 3.14159

Второй $ bar должен повторно инициализировать ранее созданный экземпляр $ foo. Внутри моего реального класса я делаю несколько вещей на eat_cpu_and_database_resources(), который называется get_weighted_tags(): вычислять взвешенное облако тегов из значений в $foo->tags. $foo->tags() был заполнен дорогими $foo->add_tag() звонками. Я хотел бы теперь получать подготовленный и заполненный экземпляр из кэша.

Я попытался просто извлечь из (сериализованного) кэша в __construct () и назначить полученный экземпляр для $this, что недопустимо в PHP:

  function __construct ($id) {
    if ($cached = $this->cache_get($id)) {
      $this = $cached
    } 
    else {
      #initialize normally
    }
  }

Это правильный путь? Или я должен обрабатывать каждый экземпляр уникальным и вместо этого применять кэширование в методе eat_cpu_and_database_resources() вместо кэширования всего экземпляра?

Есть ли в PHP встроенный способ восстановления старых экземпляров (в новом потоке)?

1 Ответ

2 голосов
/ 15 апреля 2011

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

Если вы хотите отменить сериализацию объекта из внутреннего формата PHP, вы должны использовать соответствующий метод unserialize и, возможно, захотите добавить magic __wakeup метод в делать любые повторные инициализации сообщения:

Предполагаемое использование __wakeup - восстановить все подключения к базе данных, которые могли быть потеряны во время сериализации, и выполнить другие задачи повторной инициализации.

Поскольку для этого вам необходимо сначала получить сериализованную строку, вам может потребоваться добавить некоторые средства для инкапсуляции этой логики, такие как шаблон Factory или Builder или выделенный FooCache.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...