Skip to content

The Container Lifecycle ​

This library's headline feature is compilation: the expensive work of reading your .ctn files and resolving the dependency graph happens once, at build time, and produces a plain PHP class. At runtime you just include that class and resolve services from it — there is almost no overhead.

Understanding this pipeline explains why the API is shaped the way it is.

The pipeline ​

  app.ctn (source text)
        │
        ▼
   ContainerLexer        tokenizes the .ctn source
        │
        ▼
      Parser             builds an AST of Nodes
        │
        ▼
 ContainerInterpreter    walks the AST, fills a…
        │
        ▼
 ContainerNamespace      the "pot" of parsed parameters + service definitions
        │  (importNamespace)
        ▼
 ContainerBuilder        code-generates a Container subclass…
        │  (generate)
        ▼
 Generated PHP class     one resolver method per service, written to cache/
        │  (require + new)
        ▼
   Container instance    fast runtime resolution — get(), has(), …

Everything above the generated class is build-time and runs only when the cache is (re)built. Everything below is runtime.

Who drives it ​

For the recommended setup you never touch the lexer, parser or interpreter directly. The ContainerFactory orchestrates the whole thing:

php
$factory = new \ClanCats\Container\ContainerFactory(__DIR__ . '/cache');

$container = $factory->create('AppContainer', function($builder) {
    $namespace = new \ClanCats\Container\ContainerNamespace();
    $namespace->parse(__DIR__ . '/app.ctn');   // source → namespace
    $builder->importNamespace($namespace);      // namespace → builder
});

create() does the following:

  1. If a class named AppContainer is already loaded, it returns a new instance immediately.
  2. Otherwise it looks for a cached file (cache/AppContainer.php).
  3. If that file is missing — or debug mode is on — it runs your callback, code-generates the class and writes it to the cache directory.
  4. It requires the cache file and returns new AppContainer($initialParameters).

So the parsing/building steps only ever run when the cache file is absent.

Debug mode ​

Because create() rebuilds only when the cache file is missing, editing an .ctn file during development would not take effect until you delete the cache. Debug mode forces a rebuild on every call:

php
$factory = new \ClanCats\Container\ContainerFactory(__DIR__ . '/cache', true); // debug on

Turn it off in production so the cached class is reused.

Where to go next ​