From bde85ec16c4744b78f51ca1ab8b58d2d762084da Mon Sep 17 00:00:00 2001 From: Vlad Varlamov Date: Sat, 23 Mar 2024 06:59:02 +0400 Subject: [PATCH] Added `yii\caching\CallbackDependency` to allow using a callback to determine if a cache dependency is still valid --- docs/guide-es/caching-data.md | 1 + docs/guide-fr/caching-data.md | 2 +- docs/guide-ja/caching-data.md | 2 +- docs/guide-pt-BR/caching-data.md | 2 +- docs/guide-ru/caching-data.md | 1 + docs/guide-zh-CN/caching-data.md | 2 +- docs/guide/caching-data.md | 2 +- framework/CHANGELOG.md | 1 + framework/caching/CallbackDependency.php | 39 ++++++++++++++++++ framework/caching/FileDependency.php | 6 ++- framework/classes.php | 1 + .../caching/CallbackDependencyTest.php | 41 +++++++++++++++++++ 12 files changed, 94 insertions(+), 6 deletions(-) create mode 100644 framework/caching/CallbackDependency.php create mode 100644 tests/framework/caching/CallbackDependencyTest.php diff --git a/docs/guide-es/caching-data.md b/docs/guide-es/caching-data.md index 1349865d064..7aa09cd71c0 100644 --- a/docs/guide-es/caching-data.md +++ b/docs/guide-es/caching-data.md @@ -191,6 +191,7 @@ Aquí abajo se muestra un sumario de las dependencias disponibles: - [[yii\caching\ChainedDependency]]: la dependencia cambia si cualquiera de las dependencias en la cadena cambia. - [[yii\caching\DbDependency]]: la dependencia cambia si el resultado de la consulta de la sentencia SQL especificada cambia. - [[yii\caching\ExpressionDependency]]: la dependencia cambia si el resultado de la expresión de PHP especificada cambia. +- [[yii\caching\CallbackDependency]]: la dipendenza viene modificata se il risultato della callback PHP specificata cambia. - [[yii\caching\FileDependency]]: la dependencia cambia si se modifica la última fecha de modificación del archivo. - [[yii\caching\TagDependency]]: marca un elemento de datos en caché con un nombre de grupo. Puedes invalidar los elementos de datos almacenados en caché con el mismo nombre del grupo a la vez llamando a [[yii\caching\TagDependency::invalidate()]]. diff --git a/docs/guide-fr/caching-data.md b/docs/guide-fr/caching-data.md index 01979d539b3..5f5cdcb8ae0 100644 --- a/docs/guide-fr/caching-data.md +++ b/docs/guide-fr/caching-data.md @@ -217,6 +217,7 @@ Ci-dessous nous présentons un résumé des dépendances de mise en cache dispon - [[yii\caching\ChainedDependency]]: la dépendance est modifiée si l'une des dépendances de la chaîne est modifiée. - [[yii\caching\DbDependency]]: la dépendance est modifiée si le résultat de le requête de l'instruction SQL spécifiée est modifié. - [[yii\caching\ExpressionDependency]]: la dépendance est modifiée si le résultat de l'expression PHP spécifiée est modifié. +- [[yii\caching\CallbackDependency]]: la dépendance est modifiée si le résultat du rappel PHP spécifié est modifié. - [[yii\caching\FileDependency]]: la dépendance est modifiée si la date de dernière modification du fichier est modifiée. - [[yii\caching\TagDependency]]: associe une donnée mise en cache à une ou plusieurs balises. Vous pouvez invalider la donnée mise en cache associée à la balise spécifiée en appelant [[yii\caching\TagDependency::invalidate()]]. @@ -342,4 +343,3 @@ $result = $db->cache(function ($db) { La mise en cache de requêtes ne fonctionne pas avec des résultats de requêtes qui contiennent des gestionnaires de ressources. Par exemple, lorsque vous utilisez de type de colonne `BLOB` dans certains systèmes de gestion de bases de données (DBMS), la requête retourne un gestionnaire de ressources pour la donnée de la colonne. Quelques supports de stockage pour cache sont limités en taille. Par exemple, avec memcache, chaque entrée est limitée en taille à 1 MO. En conséquence, si le résultat d'une requête dépasse cette taille, la mise en cache échoue. - diff --git a/docs/guide-ja/caching-data.md b/docs/guide-ja/caching-data.md index d2ae54e6fa6..e0d82eda602 100644 --- a/docs/guide-ja/caching-data.md +++ b/docs/guide-ja/caching-data.md @@ -275,6 +275,7 @@ $data = $cache->get($key); - [[yii\caching\ChainedDependency]]: チェーン上のいずれかの依存が変更された場合に、依存が変更されます。 - [[yii\caching\DbDependency]]: 指定された SQL 文のクエリ結果が変更された場合、依存が変更されます。 - [[yii\caching\ExpressionDependency]]: 指定された PHP の式の結果が変更された場合、依存が変更されます。 +- [[yii\caching\CallbackDependency]]: 指定されたPHPコールバックの結果が変更された場合、依存関係は変更されます。 - [[yii\caching\FileDependency]]: ファイルの最終更新日時が変更された場合、依存が変更されます。 - [[yii\caching\TagDependency]]: キャッシュされるデータ・アイテムに一つまたは複数のタグを関連付けます。 [[yii\caching\TagDependency::invalidate()]] を呼び出すことによって、指定されたタグ (複数可) を持つキャッシュされたデータ・アイテムを無効にすることができます。 @@ -431,4 +432,3 @@ $result = $db->cache(function ($db) { > Info: デフォルトでは、コンソール・アプリケーションは独立した構成情報ファイルを使用します。 正しい結果を得るためには、ウェブとコンソールのアプリケーション構成で同じキャッシュ・コンポーネントを使用していることを確認してください。 - diff --git a/docs/guide-pt-BR/caching-data.md b/docs/guide-pt-BR/caching-data.md index 3801b355a1e..3ac696c8208 100644 --- a/docs/guide-pt-BR/caching-data.md +++ b/docs/guide-pt-BR/caching-data.md @@ -229,6 +229,7 @@ Abaixo um sumário das dependências de cache disponíveis: - [[yii\caching\DbDependency]]: a dependência muda caso o resultado da consulta especificada pela instrução SQL seja alterado. - [[yii\caching\ExpressionDependency]]: a dependência muda se o resultado da expressão PHP especificada for alterado. +- [[yii\caching\CallbackDependency]]: a dependência é alterada se o resultado do callback PHP especificado for alterado.. - [[yii\caching\FileDependency]]: A dependência muda se a data da última alteração do arquivo for alterada. - [[yii\caching\TagDependency]]: associa um registro em cache com uma ou múltiplas tags. Você pode invalidar os registros em cache com a tag especificada ao chamar [[yii\caching\TagDependency::invalidate()]]. @@ -352,4 +353,3 @@ O cache de consulta não funciona com resultados de consulta que contêm mani Por exemplo, ao usar o tipo de coluna `BLOB` em alguns SGBDs, o resultado da consulta retornará um manipulador de recurso (resource handler) para o registro na coluna. Alguns armazenamentos em cache têm limitações de tamanho. Por exemplo, memcache limita o uso máximo de espaço de 1MB para cada registro. Então, se o tamanho do resultado de uma consulta exceder este limite, o cache falhará. - diff --git a/docs/guide-ru/caching-data.md b/docs/guide-ru/caching-data.md index 7b1a3052e29..d68bbfdb178 100644 --- a/docs/guide-ru/caching-data.md +++ b/docs/guide-ru/caching-data.md @@ -221,6 +221,7 @@ $data = $cache->get($key); - [[yii\caching\ChainedDependency]]: зависимость меняется, если любая зависимость в цепочке изменяется; - [[yii\caching\DbDependency]]: зависимость меняется, если результат некоторого определенного SQL запроса изменён; - [[yii\caching\ExpressionDependency]]: зависимость меняется, если результат определенного PHP выражения изменён; +- [[yii\caching\CallbackDependency]]: зависимость меняется, если результат коллбэк функции изменён; - [[yii\caching\FileDependency]]: зависимость меняется, если изменилось время последней модификации файла; - [[yii\caching\TagDependency]]: Связывает кэшированные данные элемента с одним или несколькими тегами. Вы можете аннулировать кэширование данных элементов с заданным тегом(тегами) по вызову. [[yii\caching\TagDependency::invalidate()]]; diff --git a/docs/guide-zh-CN/caching-data.md b/docs/guide-zh-CN/caching-data.md index 046c85f4124..2fd3e3cfa51 100644 --- a/docs/guide-zh-CN/caching-data.md +++ b/docs/guide-zh-CN/caching-data.md @@ -275,6 +275,7 @@ $data = $cache->get($key); - [[yii\caching\ChainedDependency]]:如果依赖链上任何一个依赖产生变化,则依赖改变。 - [[yii\caching\DbDependency]]:如果指定 SQL 语句的查询结果发生了变化,则依赖改变。 - [[yii\caching\ExpressionDependency]]:如果指定的 PHP 表达式执行结果发生变化,则依赖改变。 +- [[yii\caching\CallbackDependency]]:如果指定的PHP回调结果发生变化,依赖性将改变。 - [[yii\caching\FileDependency]]:如果文件的最后修改时间发生变化,则依赖改变。 - [[yii\caching\TagDependency]]:将缓存的数据项与一个或多个标签相关联。 您可以通过调用  [[yii\caching\TagDependency::invalidate()]] 来检查指定标签的缓存数据项是否有效。 @@ -431,4 +432,3 @@ $result = $db->cache(function ($db) { > Info: 默认情况下,控制台应用使用独立的配置文件。 所以,为了上述命令发挥作用,请确保 Web 应用和控制台应用配置相同的缓存组件。 - diff --git a/docs/guide/caching-data.md b/docs/guide/caching-data.md index 1c712e801d0..2666e544d4f 100644 --- a/docs/guide/caching-data.md +++ b/docs/guide/caching-data.md @@ -277,6 +277,7 @@ Below is a summary of the available cache dependencies: - [[yii\caching\ChainedDependency]]: the dependency is changed if any of the dependencies on the chain is changed. - [[yii\caching\DbDependency]]: the dependency is changed if the query result of the specified SQL statement is changed. - [[yii\caching\ExpressionDependency]]: the dependency is changed if the result of the specified PHP expression is changed. +- [[yii\caching\CallbackDependency]]: the dependency is changed if the result of the specified PHP callback is changed. - [[yii\caching\FileDependency]]: the dependency is changed if the file's last modification time is changed. - [[yii\caching\TagDependency]]: associates a cached data item with one or multiple tags. You may invalidate the cached data items with the specified tag(s) by calling [[yii\caching\TagDependency::invalidate()]]. @@ -433,4 +434,3 @@ You can flush the cache from the console by calling `yii cache/flush` as well. > Info: Console application uses a separate configuration file by default. Ensure, that you have the same caching components in your web and console application configs to reach the proper effect. - diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 78ddfdcbb70..5053d7cfd80 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -21,6 +21,7 @@ Yii Framework 2 Change Log - Enh #20032: Added `yii\helpers\BaseStringHelper::mask()` method for string masking with multibyte support (salehhashemi1992) - Enh #20034: Added `yii\helpers\BaseStringHelper::findBetween()` to retrieve a substring that lies between two strings (salehhashemi1992) - Enh #20121: Added `yiisoft/yii2-coding-standards` to composer `require-dev` and lint code to comply with PSR12 (razvanphp) +- Added `yii\caching\CallbackDependency` to allow using a callback to determine if a cache dependency is still valid (laxity7) 2.0.49.2 October 12, 2023 diff --git a/framework/caching/CallbackDependency.php b/framework/caching/CallbackDependency.php new file mode 100644 index 00000000000..4ee48c975ff --- /dev/null +++ b/framework/caching/CallbackDependency.php @@ -0,0 +1,39 @@ + + * @since 2.0.50 + */ +class CallbackDependency extends Dependency +{ + /** + * @var callable the PHP callback that will be called to determine if the dependency has been changed. + */ + public $callback; + + + /** + * Generates the data needed to determine if dependency has been changed. + * This method returns the result of the callback function. + * @param CacheInterface $cache the cache component that is currently evaluating this dependency + * @return mixed the data needed to determine if dependency has been changed. + */ + protected function generateDependencyData($cache) + { + return call_user_func($this->callback); + } +} diff --git a/framework/caching/FileDependency.php b/framework/caching/FileDependency.php index 61b9b610547..a9c5a8005d4 100644 --- a/framework/caching/FileDependency.php +++ b/framework/caching/FileDependency.php @@ -45,7 +45,11 @@ protected function generateDependencyData($cache) } $fileName = Yii::getAlias($this->fileName); + if (!file_exists($fileName)) { + return 0; + } + clearstatcache(false, $fileName); - return @filemtime($fileName); + return filemtime($fileName); } } diff --git a/framework/classes.php b/framework/classes.php index b65d50c7788..f9ee94d24f8 100644 --- a/framework/classes.php +++ b/framework/classes.php @@ -81,6 +81,7 @@ 'yii\caching\Dependency' => YII2_PATH . '/caching/Dependency.php', 'yii\caching\DummyCache' => YII2_PATH . '/caching/DummyCache.php', 'yii\caching\ExpressionDependency' => YII2_PATH . '/caching/ExpressionDependency.php', + 'yii\caching\CallbackDependency' => YII2_PATH . '/caching/CallbackDependency.php', 'yii\caching\FileCache' => YII2_PATH . '/caching/FileCache.php', 'yii\caching\FileDependency' => YII2_PATH . '/caching/FileDependency.php', 'yii\caching\MemCache' => YII2_PATH . '/caching/MemCache.php', diff --git a/tests/framework/caching/CallbackDependencyTest.php b/tests/framework/caching/CallbackDependencyTest.php new file mode 100644 index 00000000000..b2a93ff9541 --- /dev/null +++ b/tests/framework/caching/CallbackDependencyTest.php @@ -0,0 +1,41 @@ +callback = function () use (&$dependencyValue) { + return $dependencyValue === true; + }; + + $dependency->evaluateDependency($cache); + $this->assertFalse($dependency->isChanged($cache)); + + $dependencyValue = false; + $this->assertTrue($dependency->isChanged($cache)); + } + + public function testDependencyNotChanged() + { + $cache = new ArrayCache(); + + $dependency = new CallbackDependency(); + $dependency->callback = function () { + return 2 + 2; + }; + + $dependency->evaluateDependency($cache); + $this->assertFalse($dependency->isChanged($cache)); + $this->assertFalse($dependency->isChanged($cache)); + } +}