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

Config Cache Bundle Laravel Package

yahoojapan/config-cache-bundle

A Symfony bundle for Yahoo Japan that caches configuration values, letting you load and reuse config data efficiently without repeated parsing. Useful for projects needing lightweight config caching within a Symfony bundle context.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle is a thin Symfony wrapper around Symfony\Component\Config\ConfigCache, aimed at the very common problem of parsing a user-defined config file (YAML/JSON/INI) on every request. Instead of re-parsing, you compile it once to a PHP file and require that on subsequent requests, recompiling only when the source changes.

Minimal setup (Symfony 2.8/3.x era — this is pre-flex, so bundle registration is manual):

composer require yahoojapan/config-cache-bundle
// app/AppKernel.php
$bundles = [
    // ...
    new YahooJapan\ConfigCacheBundle\YahooJapanConfigCacheBundle(),
];
# app/config/config.yml
yahoo_japan_config_cache:
    cache_dir: "%kernel.cache_dir%/user_config"
    debug:     "%kernel.debug%"

Where to look first:

  1. DependencyInjection/Configuration.php — the only two knobs that matter are the cache directory and the debug flag.
  2. Resources/config/services.yml — confirm the exact service id/alias for the cache factory (this is a 2016 bundle; do not assume the id from the README still matches services.yml).
  3. The cache wrapper class itself — check whether it delegates straight to Symfony\Component\Config\ConfigCache. If it does, the whole bundle's behavior is already documented by Symfony's ConfigCache docs.

First use case: you have something like app/config/pricing.yml that changes rarely but is read on every request. Put it behind the cache, require the compiled PHP array, and drop the YAML parser from the hot path.

Implementation Patterns

Read-through with a factory. Inject the bundle's cache factory (or the ConfigCache service) and create one cache file per logical config domain. Don't share one file across unrelated configs — a change to pricing would invalidate routing.

public function getPricing(): array
{
    $cache = $this->configCacheFactory->create($this->cacheDir . '/pricing.php');

    if ($cache->isFresh()) {
        return require $cache->getPath();
    }

    $data = $this->yaml->parse(file_get_contents($this->sourceFile));

    $cache->write(
        '<?php return ' . var_export($data, true) . ';',
        [new \Symfony\Component\Config\Resource\FileResource($this->sourceFile)]
    );

    return $data;
}

The key discipline: the code path that reads the cache and the code path that writes it must return the same shape. require a file that returns an array; never rely on the return value of write().

Wire debug to kernel.debug. In dev you want the cache always considered stale (or at least eagerly refreshed) so editing the YAML is reflected immediately; in prod let isFresh() do mtime checks. This mirrors how Symfony's own container cache behaves and is why the bundle exposes a debug config key at all.

Hook a cache warmer. If config parsing is non-trivial, don't rebuild it during a user request at all. Implement CacheWarmerInterface and call the same provider method from warmUp(). That makes cache:clear and deploys deterministic and keeps the first request after deploy fast:

class PricingCacheWarmer implements CacheWarmerInterface
{
    public function warmUp($cacheDir) { $this->provider->getPricing(); }
    public function isOptional() { return true; }
}

Per-domain files, one resource each. Create one cache file per source file (pricing.php, features.php, routing.php) and pass only that source as a FileResource. If one YAML imports others, add all of them as resources so a change to any imported file invalidates the compiled output.

Track non-file inputs. If your user config depends on an env var, a DB row, or a feature-flag service, isFresh() cannot see it. Either write a tiny version-stamp file and register it as a FileResource, or bypass freshness in those cases. The bundle only knows about resources you hand it.

Prefer a plain compiled array for hot data. Keep the cached content to scalars and arrays. If you need objects, compile to a factory closure or a small generated class instead of var_export-ing an object graph — you'll avoid the "works locally, fatal on prod" class of bugs.

Gotchas and Tips

  • This is effectively unmaintained. Last release 2016-07-14, 6 stars, zero dependents. It targets Symfony 2.8/3.x and predates the config_cache_factory service that Symfony ships natively from 3.3 onward. If you are on any supported Symfony version, use Symfony\Component\Config\ConfigCacheFactory directly — it is the same thing, maintained, and already wired into the container. Treat this bundle as a reference implementation to copy, not a dependency to add.
  • API drift. Symfony changed ConfigCache/ResourceInterface signatures across 3.3/4.0. Confirm the wrapper compiles against your Symfony version before committing; the "no dependents" status means nobody has reported compatibility breakage for you.
  • isFresh() is mtime-based. It does not hash content. Clock skew between build hosts, touch preserving timestamps, or a deploy that rewrites the source without changing mtime will silently serve stale config. For content-sensitive configs, use a SelfCheckingResourceInterface resource or include a content hash in the cache filename.
  • Write atomicity. ConfigCache::write() writes a temp file and renames, but if you fan out concurrent warmups or regenerate on-request in prod, add a lock around the read-compile-write sequence. A half-written PHP file that gets required is a fatal error, not a stale value.
  • Opcache. With opcache.validate_timestamps=0, rewriting the cache file does not refresh the compiled opcode. After write(), call opcache_invalidate($cache->getPath(), true) on deploy, or rely on a full FPM reload.
  • cache:clear deletes your cache dir. Every consumer must be able to rebuild from scratch. Don't store anything in that directory that can't be regenerated from the source config.
  • Validate before writing. If the source YAML is malformed, don't let a partial/empty array get compiled and cached — parse, validate, then write.
  • require a file that doesn't return yields 1, not your data. Always end generated files with return ...; and treat a non-array result as a cache miss/corruption.
  • Extension points are just parameters. The bundle's surface is essentially cache_dir and debug; if you need more (custom resource tracking, alternate serializer), subclass/override the service definition in your app config rather than expecting bundle hooks that a 2016 project almost certainly doesn't have.
  • Debug in prod defeats the purpose. Double-check that %kernel.debug% resolves to false in your production container; otherwise every request recompiles and you've added overhead instead of removing it.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect