{"id":34938952,"url":"https://github.com/phpnomad/cache","last_synced_at":"2026-05-15T16:02:47.988Z","repository":{"id":244274148,"uuid":"701579918","full_name":"phpnomad/cache","owner":"phpnomad","description":"Caching abstraction layer with logger integration and storage-agnostic strategies","archived":false,"fork":false,"pushed_at":"2026-04-10T02:09:36.000Z","size":65,"stargazers_count":0,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-04-10T04:11:50.227Z","etag":null,"topics":["cache","caching","framework","php","phpnomad","platform-agnostic"],"latest_commit_sha":null,"homepage":"https://phpnomad.com","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/phpnomad.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-10-07T01:08:22.000Z","updated_at":"2026-04-10T02:09:40.000Z","dependencies_parsed_at":"2024-06-13T19:56:09.278Z","dependency_job_id":"70774e1f-0a7a-4891-a2ec-16a656c7c3fb","html_url":"https://github.com/phpnomad/cache","commit_stats":null,"previous_names":["phpnomad/cache"],"tags_count":3,"template":false,"template_full_name":"phpnomad/repository-template","purl":"pkg:github/phpnomad/cache","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpnomad%2Fcache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpnomad%2Fcache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpnomad%2Fcache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpnomad%2Fcache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phpnomad","download_url":"https://codeload.github.com/phpnomad/cache/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phpnomad%2Fcache/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33071582,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T11:35:32.926Z","status":"ssl_error","status_checked_at":"2026-05-15T11:35:31.362Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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","caching","framework","php","phpnomad","platform-agnostic"],"created_at":"2025-12-26T18:49:15.028Z","updated_at":"2026-05-15T16:02:47.976Z","avatar_url":"https://github.com/phpnomad.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# phpnomad/cache\n\n[![Latest Version](https://img.shields.io/packagist/v/phpnomad/cache.svg)](https://packagist.org/packages/phpnomad/cache)\n[![Total Downloads](https://img.shields.io/packagist/dt/phpnomad/cache.svg)](https://packagist.org/packages/phpnomad/cache)\n[![PHP Version](https://img.shields.io/packagist/php-v/phpnomad/cache.svg)](https://packagist.org/packages/phpnomad/cache)\n[![License](https://img.shields.io/packagist/l/phpnomad/cache.svg)](https://packagist.org/packages/phpnomad/cache)\n\n`phpnomad/cache` defines the caching contract for PHPNomad applications. It gives you a backend-agnostic `CacheStrategy` interface, a `CachePolicy` contract for deciding what gets cached and for how long, a `CacheableService` that wires the two together with event broadcasting, and helpers for key generation and in-memory instance caching.\n\nThe package itself is an abstraction. The concrete backend comes from an integration package like `phpnomad/symfony-cache-integration`, which adapts Symfony's Cache component to this interface. Your application code depends only on the interface, so swapping the backend later never touches your business logic. The cache layer in this package powers [Siren](https://sirenaffiliates.com) and other production PHPNomad apps.\n\n## Installation\n\n```bash\ncomposer require phpnomad/cache\n```\n\nYou will also need a concrete cache backend such as `phpnomad/symfony-cache-integration` bound to `CacheStrategy` in your container.\n\n## Quick Start\n\nInject `CacheStrategy` into any service that needs a read-through cache. The interface exposes `get`, `set`, `exists`, `delete`, and `clear`. A miss on `get` throws `CachedItemNotFoundException`, which you catch to fall back to your source of truth.\n\n```php\n\u003c?php\n\nnamespace MyApp\\Widgets;\n\nuse PHPNomad\\Cache\\Exceptions\\CachedItemNotFoundException;\nuse PHPNomad\\Cache\\Interfaces\\CacheStrategy;\n\nclass WidgetRepository\n{\n    protected const CACHE_TTL = 3600;\n\n    protected CacheStrategy $cache;\n    protected WidgetApiClient $api;\n\n    public function __construct(CacheStrategy $cache, WidgetApiClient $api)\n    {\n        $this-\u003ecache = $cache;\n        $this-\u003eapi = $api;\n    }\n\n    public function findById(int $id): Widget\n    {\n        $key = 'widget_' . $id;\n\n        try {\n            return $this-\u003ecache-\u003eget($key);\n        } catch (CachedItemNotFoundException $e) {\n            $widget = $this-\u003eapi-\u003efetchWidget($id);\n            $this-\u003ecache-\u003eset($key, $widget, self::CACHE_TTL);\n\n            return $widget;\n        }\n    }\n\n    public function invalidate(int $id): void\n    {\n        $this-\u003ecache-\u003edelete('widget_' . $id);\n    }\n}\n```\n\nThe container resolves `CacheStrategy` to whichever concrete implementation you've bound at bootstrap time, so `WidgetRepository` never references Symfony, Redis, or any specific cache backend. If you want the read-through pattern pre-built with event broadcasting on misses, you can compose `CacheableService` instead of writing the try/catch yourself.\n\n## Key Concepts\n\n- `CacheStrategy` defines the backend contract with `get`, `set`, `delete`, `exists`, and `clear`.\n- `CachePolicy` decides whether a given operation should be cached, computes the TTL, and flags when a write operation should invalidate the cache.\n- `CacheableService` composes a `CacheStrategy` and a `CachePolicy` into a read-through helper that broadcasts a `CacheMissed` event on misses, letting event listeners react to cache behavior.\n- `HashedCacheKeyFactory` generates cache keys from a context array using a configurable prefix and a hashed suffix, which keeps keys stable and short even when the context is large.\n- `WithInstanceCache` is a trait for per-instance in-memory caching, useful for collapsing repeated lookups inside a single request.\n\n## Documentation\n\nFull documentation lives at [phpnomad.com](https://phpnomad.com).\n\n## License\n\nLicensed under the [MIT License](LICENSE.txt).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphpnomad%2Fcache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphpnomad%2Fcache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphpnomad%2Fcache/lists"}