2017-05-16 25 views
0

Symfony 3.1のcache componentを使用して、自分のエンティティのカスタムメタデータを保存します。これらのメタデータに関連付けられたファイルが変更されるとすぐに無効にしたいと思います。Symfony 3.1キャッシュコンポーネントのキャッシュ無効化

特にSymfonyやキャッシュコンポーネントに特定の方法を教えてもらえませんでした特定のファイル群の変更を監視します、何か不足していますか?

<?php 
class MetadataCacheFactory implements MetadataCacheFactoryInterface 
{ 
    const CACHE_NAMESPACE = 'my_namespace'; 

    /** @var string */ 
    protected $cacheDir; 

    public function __construct(KernelInterface $kernel) 
    { 
     $this->cacheDir = $kernel->getCacheDir(); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function create(): CacheItemPoolInterface 
    { 
     return AbstractAdapter::createSystemCache(self::CACHE_NAMESPACE, 0, null, $this->cacheDir); 
    } 
} 

そして、それを使用してコード:

<?php 
class ExampleMetadataFactory implements MetadataFactoryInterface 
{ 
    const CACHE_KEY = 'example_metadata'; 

    [...] 

    /** @var ExampleMetadata */ 
    protected $metadata; 

    public function __construct(MetadataCacheFactoryInterface $cacheFactory) 
    { 
     $this->cache = $cacheFactory->create(); 
     $this->metadata = null; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function create(): ExampleMetadata 
    { 
     if ($this->metadata !== null) { 
      return $this->metadata; 
     } 
     try { 
      $cacheItem = $this->cache->getItem(md5(self::CACHE_KEY)); 
      if ($cacheItem->isHit()) { 
       return $cacheItem->get(); 
      } 
     } catch (CacheException $e) { 
      // Ignore 
     } 
     $this->metadata = $this->createMetadata(); 
     if (!isset($cacheItem)) { 
      return $this->metadata; 
     } 
     $cacheItem->set($this->metadata); 
     $this->cache->save($cacheItem); 
     return $this->metadata; 
    } 
} 

私は、実行時にコードを見ると、AbstractAdapterを与えることを選択し、私は私のキャッシュ項目プールを作成するために使用するコードの下

私はPhpFilesAdapter(私は推測devで十分な公正)。

しかし、私はこのアダプタのコードに見たとき、私はこれを見つける:

<?php 
protected function doFetch(array $ids) { 
    [...] 

    foreach ($ids as $id) { 
     try { 
      $file = $this->getFile($id); 
      list($expiresAt, $values[$id]) = include $file; 
      if ($now >= $expiresAt) { 
       unset($values[$id]); 
      } 
     } catch (\Exception $e) { 
      continue; 
     } 
    } 
} 

だから何のロジックが有効期限を除き、有効期限を確認するために、まったくありません。

あなたはファイル変更時にキャッシュを無効にする方法を知っていますか(もちろん開発環境では)?または私は自分でそれを実装する必要があります..?

ありがとうございました。

答えて

1

解決策を見つけました:ConfigCache見るべきリソースの配列を与えることができ、キャッシュが読み込まれるたびに最後の変更時刻をチェックします。

<?php 
class MetadataCacheFactory implements MetadataCacheFactoryInterface 
{ 
    const CACHE_NAMESPACE = 'my_namespace'; 

    /** @var \Symfony\Component\HttpKernel\KernelInterface */ 
    protected $kernel; 

    public function __construct(KernelInterface $kernel) 
    { 
     $this->kernel = $kernel; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function create(): ConfigCache 
    { 
     return new ConfigCache($this->kernel->getCacheDir().'/'.self::CACHE_NAMESPACE, $this->kernel->isDebug()); 
    } 
} 

そして、それを使用してコード::それは他の誰かを助けることができる希望で

<?php 
class ExampleMetadataFactory implements MetadataFactoryInterface 
{ 
    const CACHE_KEY = 'example_metadata'; 

    [...] 

    /** @var ExampleMetadata */ 
    protected $metadata; 

    public function __construct(MetadataCacheFactoryInterface $cacheFactory) 
    { 
     $this->cache = $cacheFactory->create(); 
     $this->metadata = null; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function create(): ExampleMetadata 
    { 
     if ($this->metadata !== null) { 
      return $this->metadata; 
     } 
     try { 
      if ($this->cache->isFresh()) { 
       $this->metadata = unserialize(file_get_contents($this->cache->getPath())); 
       return $this->metadata; 
      } 
     } catch (CacheException $e) { 
      // Ignore 
     } 
     $resources = []; 
     $this->metadata = $this->createMetadata($resources); 
     $this->cache->write(serialize($this->metadata), $resources); 
     return $this->metadata; 
    } 

    /** 
    * Creates the metadata. 
    * 
    * @param array $resources 
    * 
    * @return ExampleMetadata 
    */ 
    protected function createMetadata(&$resources): ExampleMetadata 
    { 
     $metadata = new ExampleMetadata(); 
     $resourcesCollection = $this->resourcesCollectionFactory->create(); 
     foreach ($resourcesCollection as $resourceClass => $resourcePath) { 
      // The important part, it's an instance of \Symfony\Component\Config\Resource\FileResource. 
      $resources[] = new FileResource($resourcePath); 
      $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); 
      $metadata->registerResourceMetadata($resourceMetadata); 
     } 
     return $metadata; 
    } 
} 

上記の例は次のようになります。

関連する問題