{"id":18941213,"url":"https://github.com/reactphp/cache","last_synced_at":"2025-05-14T04:00:21.279Z","repository":{"id":6103512,"uuid":"7330955","full_name":"reactphp/cache","owner":"reactphp","description":"Async, Promise-based cache interface for ReactPHP.","archived":false,"fork":false,"pushed_at":"2025-04-01T17:31:03.000Z","size":105,"stargazers_count":424,"open_issues_count":1,"forks_count":19,"subscribers_count":12,"default_branch":"3.x","last_synced_at":"2025-05-08T03:38:04.140Z","etag":null,"topics":["cache","php","reactphp"],"latest_commit_sha":null,"homepage":"https://reactphp.org/cache/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reactphp.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["reactphp","clue","WyriHaximus"],"open_collective":"reactphp"}},"created_at":"2012-12-26T19:22:03.000Z","updated_at":"2025-05-01T19:56:30.000Z","dependencies_parsed_at":"2024-01-15T22:43:00.929Z","dependency_job_id":"621ac101-8006-44f9-bb02-730f53617092","html_url":"https://github.com/reactphp/cache","commit_stats":{"total_commits":82,"total_committers":15,"mean_commits":5.466666666666667,"dds":0.6707317073170731,"last_synced_commit":"b8795e3fb65472b38e221541da540adaad18b565"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactphp%2Fcache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactphp%2Fcache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactphp%2Fcache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reactphp%2Fcache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reactphp","download_url":"https://codeload.github.com/reactphp/cache/tar.gz/refs/heads/3.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254067062,"owners_count":22009070,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","php","reactphp"],"created_at":"2024-11-08T12:26:43.908Z","updated_at":"2025-05-14T04:00:21.214Z","avatar_url":"https://github.com/reactphp.png","language":"PHP","funding_links":["https://github.com/sponsors/reactphp","https://github.com/sponsors/clue","https://github.com/sponsors/WyriHaximus","https://opencollective.com/reactphp"],"categories":[],"sub_categories":[],"readme":"# Cache\n\n[![CI status](https://github.com/reactphp/cache/actions/workflows/ci.yml/badge.svg)](https://github.com/reactphp/cache/actions)\n[![installs on Packagist](https://img.shields.io/packagist/dt/react/cache?color=blue\u0026label=installs%20on%20Packagist)](https://packagist.org/packages/react/cache)\n\nAsync, [Promise](https://github.com/reactphp/promise)-based cache interface\nfor [ReactPHP](https://reactphp.org/).\n\n\u003e **Development version:** This branch contains the code for the upcoming v3\n\u003e release. For the code of the current stable v1 release, check out the\n\u003e [`1.x` branch](https://github.com/reactphp/cache/tree/1.x).\n\u003e\n\u003e The upcoming v3 release will be the way forward for this package. However,\n\u003e we will still actively support v1 for those not yet on the latest version.\n\u003e See also [installation instructions](#install) for more details.\n\nThe cache component provides a\n[Promise](https://github.com/reactphp/promise)-based\n[`CacheInterface`](#cacheinterface) and an in-memory [`ArrayCache`](#arraycache)\nimplementation of that.\nThis allows consumers to type hint against the interface and third parties to\nprovide alternate implementations.\nThis project is heavily inspired by\n[PSR-16: Common Interface for Caching Libraries](https://www.php-fig.org/psr/psr-16/),\nbut uses an interface more suited for async, non-blocking applications.\n\n**Table of Contents**\n\n* [Usage](#usage)\n  * [CacheInterface](#cacheinterface)\n    * [get()](#get)\n    * [set()](#set)\n    * [delete()](#delete)\n    * [getMultiple()](#getmultiple)\n    * [setMultiple()](#setmultiple)\n    * [deleteMultiple()](#deletemultiple)\n    * [clear()](#clear)\n    * [has()](#has)\n  * [ArrayCache](#arraycache)\n* [Common usage](#common-usage)\n  * [Fallback get](#fallback-get)\n  * [Fallback-get-and-set](#fallback-get-and-set)\n* [Install](#install)\n* [Tests](#tests)\n* [License](#license)\n\n## Usage\n\n### CacheInterface\n\nThe `CacheInterface` describes the main interface of this component.\nThis allows consumers to type hint against the interface and third parties to\nprovide alternate implementations.\n\n#### get()\n\nThe `get(string $key, mixed $default = null): PromiseInterface\u003cmixed\u003e` method can be used to\nretrieve an item from the cache.\n\nThis method will resolve with the cached value on success or with the\ngiven `$default` value when no item can be found or when an error occurs.\nSimilarly, an expired cache item (once the time-to-live is expired) is\nconsidered a cache miss.\n\n```php\n$cache\n    -\u003eget('foo')\n    -\u003ethen('var_dump');\n```\n\nThis example fetches the value of the key `foo` and passes it to the\n`var_dump` function. You can use any of the composition provided by\n[promises](https://github.com/reactphp/promise).\n\n#### set()\n\nThe `set(string $key, mixed $value, ?float $ttl = null): PromiseInterface\u003cbool\u003e` method can be used to\nstore an item in the cache.\n\nThis method will resolve with `true` on success or `false` when an error\noccurs. If the cache implementation has to go over the network to store\nit, it may take a while.\n\nThe optional `$ttl` parameter sets the maximum time-to-live in seconds\nfor this cache item. If this parameter is omitted (or `null`), the item\nwill stay in the cache for as long as the underlying implementation\nsupports. Trying to access an expired cache item results in a cache miss,\nsee also [`get()`](#get).\n\n```php\n$cache-\u003eset('foo', 'bar', 60);\n```\n\nThis example eventually sets the value of the key `foo` to `bar`. If it\nalready exists, it is overridden.\n\nThis interface does not enforce any particular TTL resolution, so special\ncare may have to be taken if you rely on very high precision with\nmillisecond accuracy or below. Cache implementations SHOULD work on a\nbest effort basis and SHOULD provide at least second accuracy unless\notherwise noted. Many existing cache implementations are known to provide\nmicrosecond or millisecond accuracy, but it's generally not recommended\nto rely on this high precision.\n\nThis interface suggests that cache implementations SHOULD use a monotonic\ntime source if available. Given that a monotonic time source is only\navailable as of PHP 7.3 by default, cache implementations MAY fall back\nto using wall-clock time.\nWhile this does not affect many common use cases, this is an important\ndistinction for programs that rely on a high time precision or on systems\nthat are subject to discontinuous time adjustments (time jumps).\nThis means that if you store a cache item with a TTL of 30s and then\nadjust your system time forward by 20s, the cache item SHOULD still\nexpire in 30s.\n\n#### delete()\n\nThe `delete(string $key): PromiseInterface\u003cbool\u003e` method can be used to\ndelete an item from the cache.\n\nThis method will resolve with `true` on success or `false` when an error\noccurs. When no item for `$key` is found in the cache, it also resolves\nto `true`. If the cache implementation has to go over the network to\ndelete it, it may take a while.\n\n```php\n$cache-\u003edelete('foo');\n```\n\nThis example eventually deletes the key `foo` from the cache. As with\n`set()`, this may not happen instantly and a promise is returned to\nprovide guarantees whether or not the item has been removed from cache.\n\n#### getMultiple()\n\nThe `getMultiple(iterable\u003cstring\u003e $keys, mixed $default = null): PromiseInterface\u003citerable\u003cstring,mixed\u003e\u003e` method can be used to\nretrieve multiple cache items by their unique keys.\n\nThis method will resolve with an array of cached values on success or with the\ngiven `$default` value when an item can not be found or when an error occurs.\nSimilarly, an expired cache item (once the time-to-live is expired) is\nconsidered a cache miss.\n\n```php\n$cache-\u003egetMultiple(['name', 'age'])-\u003ethen(function (iterable $values): void {\n    $array = is_array($values) ? $values : iterator_to_array($values);\n    $name = $array['name'] ?? 'User';\n    $age = $array['age'] ?? 'n/a';\n\n    echo $name . ' is ' . $age . PHP_EOL;\n});\n```\n\nThis example fetches the cache items for the `name` and `age` keys and\nprints some example output. You can use any of the composition provided\nby [promises](https://github.com/reactphp/promise).\n\n#### setMultiple()\n\nThe `setMultiple(iterable\u003cstring,mixed\u003e $values, ?float $ttl = null): PromiseInterface\u003cbool\u003e` method can be used to\npersist a set of key =\u003e value pairs in the cache, with an optional TTL.\n\nThis method will resolve with `true` on success or `false` when an error\noccurs. If the cache implementation has to go over the network to store\nit, it may take a while.\n\nThe optional `$ttl` parameter sets the maximum time-to-live in seconds\nfor these cache items. If this parameter is omitted (or `null`), these items\nwill stay in the cache for as long as the underlying implementation\nsupports. Trying to access an expired cache items results in a cache miss,\nsee also [`getMultiple()`](#getmultiple).\n\n```php\n$cache-\u003esetMultiple(['foo' =\u003e 1, 'bar' =\u003e 2], 60);\n```\n\nThis example eventually sets the list of values - the key `foo` to `1` value \nand the key `bar` to `2`. If some of the keys already exist, they are overridden.\n\n#### deleteMultiple()\n\nThe `setMultiple(iterable\u003cstring\u003e $keys): PromiseInterface\u003cbool\u003e` method can be used to\ndelete multiple cache items in a single operation.\n\nThis method will resolve with `true` on success or `false` when an error\noccurs. When no items for `$keys` are found in the cache, it also resolves\nto `true`. If the cache implementation has to go over the network to\ndelete it, it may take a while.\n\n```php\n$cache-\u003edeleteMultiple(['foo', 'bar, 'baz']);\n```\n\nThis example eventually deletes keys `foo`, `bar` and `baz` from the cache. \nAs with `setMultiple()`, this may not happen instantly and a promise is returned to\nprovide guarantees whether or not the item has been removed from cache.\n\n#### clear()\n\nThe `clear(): PromiseInterface\u003cbool\u003e` method can be used to\nwipe clean the entire cache.\n\nThis method will resolve with `true` on success or `false` when an error\noccurs. If the cache implementation has to go over the network to\ndelete it, it may take a while.\n\n```php\n$cache-\u003eclear();\n```\n\nThis example eventually deletes all keys from the cache. As with `deleteMultiple()`, \nthis may not happen instantly and a promise is returned to provide guarantees \nwhether or not all the items have been removed from cache.\n\n#### has()\n\nThe `has(string $key): PromiseInterface\u003cbool\u003e` method can be used to\ndetermine whether an item is present in the cache.\n\nThis method will resolve with `true` on success or `false` when no item can be found \nor when an error occurs. Similarly, an expired cache item (once the time-to-live \nis expired) is considered a cache miss.\n\n```php\n$cache\n    -\u003ehas('foo')\n    -\u003ethen('var_dump');\n```\n\nThis example checks if the value of the key `foo` is set in the cache and passes \nthe result to the `var_dump` function. You can use any of the composition provided by\n[promises](https://github.com/reactphp/promise).\n\nNOTE: It is recommended that has() is only to be used for cache warming type purposes\nand not to be used within your live applications operations for get/set, as this method\nis subject to a race condition where your has() will return true and immediately after,\nanother script can remove it making the state of your app out of date.\n\n### ArrayCache\n\nThe `ArrayCache` provides an in-memory implementation of the [`CacheInterface`](#cacheinterface).\n\n```php\n$cache = new ArrayCache();\n\n$cache-\u003eset('foo', 'bar');\n```\n\nIts constructor accepts an optional `?int $limit` parameter to limit the\nmaximum number of entries to store in the LRU cache. If you add more\nentries to this instance, it will automatically take care of removing\nthe one that was least recently used (LRU).\n\nFor example, this snippet will overwrite the first value and only store\nthe last two entries:\n\n```php\n$cache = new ArrayCache(2);\n\n$cache-\u003eset('foo', '1');\n$cache-\u003eset('bar', '2');\n$cache-\u003eset('baz', '3');\n```\n\nThis cache implementation is known to rely on wall-clock time to schedule\nfuture cache expiration times when using any version before PHP 7.3,\nbecause a monotonic time source is only available as of PHP 7.3 (`hrtime()`).\nWhile this does not affect many common use cases, this is an important\ndistinction for programs that rely on a high time precision or on systems\nthat are subject to discontinuous time adjustments (time jumps).\nThis means that if you store a cache item with a TTL of 30s on PHP \u003c 7.3\nand then adjust your system time forward by 20s, the cache item may\nexpire in 10s. See also [`set()`](#set) for more details.\n\n## Common usage\n\n### Fallback get\n\nA common use case of caches is to attempt fetching a cached value and as a\nfallback retrieve it from the original data source if not found. Here is an\nexample of that:\n\n```php\n$cache\n    -\u003eget('foo')\n    -\u003ethen(function ($result) {\n        if ($result === null) {\n            return getFooFromDb();\n        }\n        \n        return $result;\n    })\n    -\u003ethen('var_dump');\n```\n\nFirst an attempt is made to retrieve the value of `foo`. A callback function is \nregistered that will call `getFooFromDb` when the resulting value is null. \n`getFooFromDb` is a function (can be any PHP callable) that will be called if the \nkey does not exist in the cache.\n\n`getFooFromDb` can handle the missing key by returning a promise for the\nactual value from the database (or any other data source). As a result, this\nchain will correctly fall back, and provide the value in both cases.\n\n### Fallback get and set\n\nTo expand on the fallback get example, often you want to set the value on the\ncache after fetching it from the data source.\n\n```php\n$cache\n    -\u003eget('foo')\n    -\u003ethen(function ($result) {\n        if ($result === null) {\n            return $this-\u003egetAndCacheFooFromDb();\n        }\n        \n        return $result;\n    })\n    -\u003ethen('var_dump');\n\npublic function getAndCacheFooFromDb()\n{\n    return $this-\u003edb\n        -\u003eget('foo')\n        -\u003ethen([$this, 'cacheFooFromDb']);\n}\n\npublic function cacheFooFromDb($foo)\n{\n    $this-\u003ecache-\u003eset('foo', $foo);\n\n    return $foo;\n}\n```\n\nBy using chaining you can easily conditionally cache the value if it is\nfetched from the database.\n\n## Install\n\nThe recommended way to install this library is [through Composer](https://getcomposer.org).\n[New to Composer?](https://getcomposer.org/doc/00-intro.md)\n\nOnce released, this project will follow [SemVer](https://semver.org/).\nAt the moment, this will install the latest development version:\n\n```bash\ncomposer require react/cache:^3@dev\n```\n\nSee also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.\n\nThis project aims to run on any platform and thus does not require any PHP\nextensions and supports running on PHP 7.1 through current PHP 8+.\nIt's *highly recommended to use the latest supported PHP version* for this project.\n\n## Tests\n\nTo run the test suite, you first need to clone this repo and then install all\ndependencies [through Composer](https://getcomposer.org):\n\n```bash\ncomposer install\n```\n\nTo run the test suite, go to the project root and run:\n\n```bash\nvendor/bin/phpunit\n```\n\nOn top of this, we use PHPStan on max level to ensure type safety across the project:\n\n```bash\nvendor/bin/phpstan\n```\n\n## License\n\nMIT, see [LICENSE file](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactphp%2Fcache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freactphp%2Fcache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactphp%2Fcache/lists"}