Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Cache Laravel Package

fm/cache

fm/cache is a Laravel/PHP package for working with application caching. It provides a framework-friendly way to integrate cache storage and management, helping keep repeated data access fast and organized in your projects.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first. fm/cache is archived, and the final tagged release (v0.1.3) is an explicit end-of-life notice: the library has been moved to treehouselabs/cache and maintenance continues only there. That release adds no code, no fixes, no PHP 8 work — it exists purely to tell you to leave. There are zero dependents and zero stars. Do not introduce it into a new project.

The only legitimate reason to read this page is that you have inherited a codebase already requiring it. The single most useful thing this release gives you is a definitive answer to "is anything coming?" — no. Plan accordingly.

If you are starting fresh, install the successor instead:

composer require treehouselabs/cache

Before you commit to that swap, spend five minutes on the successor's repository: check its last commit date, its supported PHP versions, and whether its namespace and method signatures match what fm/cache exposed. A handoff notice is not a guarantee of parity, and a successor that is itself dormant just moves the problem.

If you must stay on fm/cache, pin the final release exactly. Note the version line is 0.1.x, not 1.x:

composer require fm/cache:^0.1.3 --with-all-dependencies

You will likely need to bump the php constraint in the root composer.json, and because 0.x versions are treated as unstable, you may need "minimum-stability": "dev" (or an explicit stability flag on this requirement) plus a VCS entry if Packagist metadata has drifted:

"repositories": [
  { "type": "vcs", "url": "https://github.com/financialmedia/cache" }
]

Where to look first. Read in this order:

  1. composer.json — note the autoload block. A 2014-era package is probably PSR-0 (FinancialMedia\Cache\ → src/FinancialMedia/Cache/) rather than PSR-4. This affects how you add your own adapters, and it also tells you how much work a move to the successor will be if the namespace changed.
  2. src/ — find the single entry point. Expect a manager/factory class (something like CacheManager or CacheFactory) that takes a driver name plus options and returns a cache object.
  3. The adapter/driver directory — one class per backend (array, filesystem, redis, memcached, maybe apc). This is the surface you actually code against, and it is the surface you will have to re-implement against the successor.
  4. tests/ — the fastest way to learn the intended API is to read the test for the array adapter; it will show you the exact method names and TTL semantics without guessing.

First use case. Wire the array adapter in your test suite and the real backend in production, then cache one expensive repository call:

$cache = $manager->getCache('redis'); // name depends on the actual factory API

$key = 'user:42:profile';
$profile = $cache->get($key);

if ($profile === null) {
    $profile = $userRepository->findProfile(42);
    $cache->save($key, $profile, 300); // verify argument order in the source
}

return $profile;

Confirm three things before going further: the exact method names (get/set vs get/save), the TTL unit (seconds vs minutes), and what a miss returns (null vs false). All three vary wildly in packages of this vintage. Write those three answers into a comment above your wrapper class — you will forget, and nobody upstream is left to ask.

Implementation Patterns

Register one manager as a singleton. Whatever the factory is called, instantiate it once at bootstrap and inject it. Rebuilding it per call re-opens connections and defeats connection pooling:

$container->singleton('cache', function ($c) {
    return new CacheManager([
        'default' => 'redis',
        'stores'  => [
            'redis'  => ['host' => '127.0.0.1', 'port' => 6379],
            'array'  => [],
            'file'   => ['path' => storage_path('cache')],
        ],
    ]);
});

Pick adapters per environment, not per call site. Array in tests, filesystem or redis in local dev, redis/memcached in production. Keep the selection in config so you can flip it without touching application code.

Use a remember-style wrapper if it exists; otherwise write one. This package predates PSR-16, so you will probably need your own thin helper to avoid repeating the get/miss/save dance everywhere:

function cache_remember($cache, string $key, int $ttl, callable $callback)
{
    $value = $cache->get($key);
    if ($value === null) {
        $value = $callback();
        $cache->save($key, $value, $ttl);
    }
    return $value;
}

Namespace every key. With no tag support, the only way to invalidate a group is to change the key prefix. Build a versioned prefix into your key helper:

$prefix = 'v' . $cache->get('schema_version', 1) . ':';
$key = $prefix . 'user:' . $id . ':profile';

Bump schema_version on deploy and the old entries become unreachable garbage that expires on its own.

Wrap the cache in a decorator for observability. Because the base class is simple, a decorator is cheap and gives you hit/miss metrics and slow-call logging without touching the library:

class InstrumentedCache
{
    public function __construct(private $inner, private $logger) {}

    public function get($key)
    {
        $hit = $this->inner->get($key) !== null;
        $this->logger->debug('cache', ['key' => $key, 'hit' => $hit]);
        // ...
    }
}

Testing. Always back the array adapter in tests and assert both branches: that a miss calls the callback and that a hit does not. Clear the array store in setUp() — stale state between tests is the number-one source of flaky cache tests.

Laravel integration. Bind the manager in a service provider, add a config/cache.php-style file mapping your driver names to the package's names, and expose a facade only if your team is already used to Cache::get(). Do not fight the framework's own cache; run them side by side and migrate call sites gradually.

Migration shim. Now that upstream has declared the successor, write an adapter that implements the old interface but delegates to treehouselabs/cache (or symfony/cache, or PSR-16). Swap the binding, then delete call sites one at a time. This is far safer than a big-bang rewrite of every ->get() in the codebase — and it is the one piece of work the final release is telling you to do.

Gotchas and Tips

It is abandoned, officially and finally. v0.1.3 is a tombstone, not a patch. There will be no security fixes, no PHP 8+ compatibility work, and no maintainer to ask. Treat that as a hard fact rather than a risk to be re-evaluated; the exit plan is now overdue by default.

Do not pin ^1.0. The final tag is 0.1.3, so ^1.0 will fail to resolve on a clean install even though older docs and blog posts suggest it. Pin the exact final tag (0.1.3) in production, and keep composer.lock committed.

PSR-0 autoloading bites you. If you add custom adapter classes, their file paths must mirror the namespace exactly. A PSR-4 autoloader in your app will not find them unless you register the prefix explicitly. The successor may well be PSR-4 — that mismatch is exactly the sort of thing that makes a "drop-in replacement" take a day instead of an hour.

TTL semantics are inconsistent across adapters. A TTL of 0 may mean "forever" in one adapter and "expire immediately" in another. Negative values are often passed straight through to the backend and behave differently in Redis versus Memcached versus the filesystem. Verify against each backend you actually use, and never rely on 0 meaning anything.

Miss values are not standardized. null versus false versus the literal cached value false are all distinct cases. If you cache booleans, get() === null is the only safe miss check. Add a sentinel wrapper if your adapter cannot distinguish.

Serialization will bite you. Objects cached from the filesystem adapter must be unserializable; closures, resources, and Eloquent-style models with live connections will fail or silently corrupt. Cache plain arrays and scalars, or explicitly implement Serializable on your DTOs.

Memcached key limits. Keys over 250 bytes or containing whitespace/control characters are rejected or silently mangled. Hash long keys: $key = 'obj:' . md5($rawKey);. Redis tolerates long keys but you will still want hashing for consistency.

No tags, no locking, no atomicity. You get stampedes on cold keys under load. Mitigate with a short "lock" key written via add-if-not-exists where the backend supports it, or by jittering TTLs so a whole keyset doesn't expire simultaneously.

flush() is a footgun. On Redis it can wipe the entire database, not just your prefix. If the adapter exposes a flush, do not call it from application code — and if you share a Redis instance, use a dedicated database number.

Failures are often silent. Many 2014-era adapters swallow connection exceptions and degrade to permanent cache misses. That masks outages but also hides misconfiguration. Log at the adapter boundary and monitor your hit rate; a sudden drop to zero is your signal.

Debugging checklist. Confirm the extension is loaded (php -m | grep redis), confirm the connection config is actually reaching the factory, then inspect the key directly in the backend (redis-cli keys 'prefix:*') to see whether writes land at all. Nine times out of ten the issue is a key mismatch, not the library.

Extension points. The realistic ones are: a custom adapter class implementing the package's cache interface, and decorators around the manager. Do not patch the vendored source — you will lose it on the next composer install, and there is no upstream left to send a PR to.

Plan the exit now. Pin 0.1.3, isolate all usages behind your own small interface, write the migration shim, and target treehouselabs/cache, symfony/cache, or PSR-16 (psr/simple-cache). Every week you leave direct fm/cache calls scattered through the codebase makes that migration more expensive — and the final release means the cost only goes up from here.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums