Skip to content

Instantly share code, notes, and snippets.

@DavertMik
Last active December 16, 2015 15:50
Show Gist options
  • Save DavertMik/5459174 to your computer and use it in GitHub Desktop.
Save DavertMik/5459174 to your computer and use it in GitHub Desktop.
Symfony Container is recreated on each request!

In Codeception functional tests we use Symfony Container to access Profiler and Doctrine to check for different data. But looks like in Symfony2 container is rebuilt on every request. So no Doctrine and no Profiler now :( Is that intentional?

Here is the stack trace I see trying to execute Symfony2 functional tests over Codeception

We start with creating Kernel and Client (in Codeception\Module\Symfony2):

<?php
$this->kernelClass = $this->getKernelClass();
$this->kernel = new $this->kernelClass('test', true);
$this->client = $this->container->get('test.client');
?>

It's pretty ok now, but on each request container is recreated. Here how it happens

We hit the router. Symfony\Component\Routing\Router

<?php

    public function getMatcher()
    {
        if (null !== $this->matcher) {
            return $this->matcher;
        }

        if (null === $this->options['cache_dir'] || null === $this->options['matcher_cache_class']) {
            return $this->matcher = new $this->options['matcher_class']($this->getRouteCollection(), $this->context);
        }

        $class = $this->options['matcher_cache_class'];
        $cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);

// trace goes here (line 235)
        if (!$cache->isFresh($class)) {
// trace goes here 
            $dumper = new $this->options['matcher_dumper_class']($this->getRouteCollection());

            $options = array(
                'class'      => $class,
                'base_class' => $this->options['matcher_base_class'],
            );

            $cache->write($dumper->dump($options), $this->getRouteCollection()->getResources());
        }

        require_once $cache;

        return $this->matcher = new $class($this->context);
    }

Now we are in ConfigCache: Symfony\Component\Config\ConfigCache

<?php

    public function isFresh()
    {
        if (!is_file($this->file)) {
            return false;
        }

        if (!$this->debug) {
            return true;
        }

        $metadata = $this->file.'.meta';
        if (!is_file($metadata)) {
            return false;
        }

        $time = filemtime($this->file);
          
// trace goes here (we are in debug mode). Line 75
        $meta = unserialize(file_get_contents($metadata));
// trace goes here
        foreach ($meta as $resource) {
            if (!$resource->isFresh($time)) {
                return false;
            }
        }

        return true;
    }

On unserialize($metadata) a new container is created.

Am I doing smth wrong or Symfony 2.2 intentionaly recreates it when debug is on?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment