Skip to content

Commit

Permalink
[DependencyInjection] optimized compiled containers
Browse files Browse the repository at this point in the history
 * removed the __call() method in Container: it means that now, there is only
   one way to get a service: via the get() method;

 * removed the $shared variable in the dumped Container classes (we now use
   the $services variable from the parent class directly -- this is where we
   have a performance improvement);

 * optimized the PHP Dumper output.
  • Loading branch information
fabpot committed Nov 23, 2010
1 parent 5e15093 commit 60bbb8f
Show file tree
Hide file tree
Showing 21 changed files with 41 additions and 123 deletions.
Expand Up @@ -56,8 +56,8 @@ protected function configure()
protected function execute(InputInterface $input, OutputInterface $output)
{
$bundleClass = null;
$bundleDirs = $this->container->getKernelService()->getBundleDirs();
foreach ($this->container->getKernelService()->getBundles() as $bundle) {
$bundleDirs = $this->container->get('kernel')->getBundleDirs();
foreach ($this->container->get('kernel')->getBundles() as $bundle) {
if (strpos(get_class($bundle), $input->getArgument('bundle')) !== false) {
$tmp = dirname(str_replace('\\', '/', get_class($bundle)));
$namespace = str_replace('/', '\\', dirname($tmp));
Expand Down
Expand Up @@ -88,7 +88,7 @@ protected function getEntityManager($name = null)

protected function runCommand($name, array $input = array())
{
$application = new Application($this->container->getKernelService());
$application = new Application($this->container->get('kernel'));
$arguments = array();
$arguments = array_merge(array($name), $input);
$input = new ArrayInput($arguments);
Expand Down
Expand Up @@ -62,7 +62,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
}

$entityGenerator = $this->getEntityGenerator();
foreach ($this->container->getKernelService()->getBundles() as $bundle) {
foreach ($this->container->get('kernel')->getBundles() as $bundle) {

// retrieve the full bundle classname
$class = $bundle->getReflection()->getName();
Expand Down
Expand Up @@ -60,7 +60,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
throw new \InvalidArgumentException('The bundle name must end with Bundle. Example: "Bundle\MySampleBundle".');
}

$dirs = $this->container->getKernelService()->getBundleDirs();
$dirs = $this->container->get('kernel')->getBundleDirs();

$tmp = str_replace('\\', '/', $bundle);
$namespace = str_replace('/', '\\', dirname($tmp));
Expand Down
Expand Up @@ -54,8 +54,8 @@ protected function configure()
protected function execute(InputInterface $input, OutputInterface $output)
{
$bundleClass = null;
$bundleDirs = $this->container->getKernelService()->getBundleDirs();
foreach ($this->container->getKernelService()->getBundles() as $bundle) {
$bundleDirs = $this->container->get('kernel')->getBundleDirs();
foreach ($this->container->get('kernel')->getBundles() as $bundle) {
if (strpos(get_class($bundle), $input->getArgument('bundle')) !== false) {
$tmp = dirname(str_replace('\\', '/', get_class($bundle)));
$namespace = str_replace('/', '\\', dirname($tmp));
Expand Down
Expand Up @@ -67,8 +67,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
$paths = is_array($dirOrFile) ? $dirOrFile : array($dirOrFile);
} else {
$paths = array();
$bundleDirs = $this->container->getKernelService()->getBundleDirs();
foreach ($this->container->getKernelService()->getBundles() as $bundle) {
$bundleDirs = $this->container->get('kernel')->getBundleDirs();
foreach ($this->container->get('kernel')->getBundles() as $bundle) {
$tmp = dirname(str_replace('\\', '/', get_class($bundle)));
$namespace = str_replace('/', '\\', dirname($tmp));
$class = basename($tmp);
Expand Down
Expand Up @@ -67,8 +67,8 @@ protected function execute(InputInterface $input, OutputInterface $output)
$paths = is_array($dirOrFile) ? $dirOrFile : array($dirOrFile);
} else {
$paths = array();
$bundleDirs = $this->container->getKernelService()->getBundleDirs();
foreach ($this->container->getKernelService()->getBundles() as $bundle) {
$bundleDirs = $this->container->get('kernel')->getBundleDirs();
foreach ($this->container->get('kernel')->getBundles() as $bundle) {
$tmp = dirname(str_replace('\\', '/', get_class($bundle)));
$namespace = str_replace('/', '\\', dirname($tmp));
$class = basename($tmp);
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bundle/FrameworkBundle/Client.php
Expand Up @@ -75,7 +75,7 @@ public function getProfiler()
return false;
}

return $this->container->getProfilerService()->loadFromResponse($this->response);
return $this->container->get('profiler')->loadFromResponse($this->response);
}

/**
Expand Down
Expand Up @@ -52,7 +52,7 @@ protected function execute(InputInterface $input, OutputInterface $output)

$filesystem = new Filesystem();

foreach ($this->container->getKernelService()->getBundles() as $bundle) {
foreach ($this->container->get('kernel')->getBundles() as $bundle) {
if (is_dir($originDir = $bundle->getPath().'/Resources/public')) {
$output->writeln(sprintf('Installing assets for <comment>%s\\%s</comment>', $bundle->getNamespacePrefix(), $bundle->getName()));

Expand Down
Expand Up @@ -51,7 +51,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
throw new \InvalidArgumentException('The namespace must end with Bundle.');
}

$dirs = $this->container->getKernelService()->getBundleDirs();
$dirs = $this->container->get('kernel')->getBundleDirs();

$tmp = str_replace('\\', '/', $namespace);
$namespace = str_replace('/', '\\', dirname($tmp));
Expand Down
Expand Up @@ -96,7 +96,7 @@ protected function createController($controller)
public function forward($controller, array $attributes = array(), array $query = array())
{
$attributes['_controller'] = $controller;
$subRequest = $this->container->getRequestService()->duplicate($query, null, $attributes);
$subRequest = $this->container->get('request')->duplicate($query, null, $attributes);

return $this->container->get('kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
}
Expand Down Expand Up @@ -137,7 +137,7 @@ public function render($controller, array $options = array())
}

if (null === $this->esiSupport) {
$this->esiSupport = $this->container->has('esi') && $this->container->getEsiService()->hasSurrogateEsiCapability($this->container->getRequestService());
$this->esiSupport = $this->container->has('esi') && $this->container->get('esi')->hasSurrogateEsiCapability($this->container->get('request'));
}

if ($this->esiSupport && $options['standalone']) {
Expand All @@ -148,10 +148,10 @@ public function render($controller, array $options = array())
$alt = $this->generateInternalUri($options['alt'][0], isset($options['alt'][1]) ? $options['alt'][1] : array(), isset($options['alt'][2]) ? $options['alt'][2] : array());
}

return $this->container->getEsiService()->renderIncludeTag($uri, $alt, $options['ignore_errors'], $options['comment']);
return $this->container->get('esi')->renderIncludeTag($uri, $alt, $options['ignore_errors'], $options['comment']);
}

$request = $this->container->getRequestService();
$request = $this->container->get('request');

// controller or URI?
if (0 === strpos($controller, '/')) {
Expand All @@ -164,7 +164,7 @@ public function render($controller, array $options = array())
}

try {
$response = $this->container->getKernelService()->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
$response = $this->container->get('kernel')->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);

if (200 != $response->getStatusCode()) {
throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $request->getUri(), $response->getStatusCode()));
Expand Down Expand Up @@ -204,10 +204,10 @@ public function generateInternalUri($controller, array $attributes = array(), ar
return $controller;
}

$uri = $this->container->getRouterService()->generate('_internal', array(
$uri = $this->container->get('router')->generate('_internal', array(
'controller' => $controller,
'path' => $attributes ? http_build_query($attributes) : 'none',
'_format' => $this->container->getRequestService()->getRequestFormat(),
'_format' => $this->container->get('request')->getRequestFormat(),
), true);

if ($query) {
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bundle/FrameworkBundle/Test/WebTestCase.php
Expand Up @@ -39,7 +39,7 @@ public function createClient(array $options = array(), array $server = array())
$this->kernel = $this->createKernel($options);
$this->kernel->boot();

$client = $this->kernel->getContainer()->getTest_ClientService();
$client = $this->kernel->getContainer()->get('test.client');
$client->setServerParameters($server);

return $client;
Expand Down
23 changes: 1 addition & 22 deletions src/Symfony/Component/DependencyInjection/Container.php
Expand Up @@ -181,9 +181,7 @@ public function has($id)
*/
public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE)
{
if (!is_string($id)) {
throw new \InvalidArgumentException(sprintf('A service id should be a string (%s given).', str_replace("\n", '', var_export($id, true))));
}
$id = (string) $id;

if (isset($this->services[$id])) {
return $this->services[$id];
Expand Down Expand Up @@ -216,25 +214,6 @@ public function getServiceIds()
return array_merge($ids, array_keys($this->services));
}

/**
* Catches unknown methods.
*
* @param string $method The called method name
* @param array $arguments The method arguments
*
* @return mixed
*
* @throws \BadMethodCallException When calling to an undefined method
*/
public function __call($method, $arguments)
{
if (!preg_match('/^get(.+)Service$/', $method, $match)) {
throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s.', get_class($this), $method));
}

return $this->get(self::underscore($match[1]));
}

static public function camelize($id)
{
return preg_replace(array('/(?:^|_)+(.)/e', '/\.(.)/e'), array("strtoupper('\\1')", "'_'.strtoupper('\\1')"), $id);
Expand Down
34 changes: 11 additions & 23 deletions src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
Expand Up @@ -60,17 +60,6 @@ protected function addServiceInclude($id, $definition)
}
}

protected function addServiceShared($id, $definition)
{
if ($definition->isShared()) {
return <<<EOF
if (isset(\$this->shared['$id'])) return \$this->shared['$id'];
EOF;
}
}

protected function addServiceReturn($id, $definition)
{
return <<<EOF
Expand All @@ -94,20 +83,22 @@ protected function addServiceInstance($id, $definition)
$arguments[] = $this->dumpValue($value);
}

if ($definition->isShared()) {
$instantiation = sprintf(" \$this->services['$id'] = \$instance");
} else {
$instantiation = sprintf(" \$instance");
}

if (null !== $definition->getFactoryMethod()) {
if (null !== $definition->getFactoryService()) {
$code = sprintf(" \$instance = %s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService()), $definition->getFactoryMethod(), implode(', ', $arguments));
$code = sprintf("$instantiation = %s->%s(%s);\n", $this->getServiceCall($definition->getFactoryService()), $definition->getFactoryMethod(), implode(', ', $arguments));
} else {
$code = sprintf(" \$instance = call_user_func(array(%s, '%s')%s);\n", $class, $definition->getFactoryMethod(), $arguments ? ', '.implode(', ', $arguments) : '');
$code = sprintf("$instantiation = call_user_func(array(%s, '%s')%s);\n", $class, $definition->getFactoryMethod(), $arguments ? ', '.implode(', ', $arguments) : '');
}
} elseif ($class != "'".str_replace('\\', '\\\\', $definition->getClass())."'") {
$code = sprintf(" \$class = %s;\n \$instance = new \$class(%s);\n", $class, implode(', ', $arguments));
} elseif (false !== strpos($class, '$')) {
$code = sprintf(" \$class = %s;\n$instantiation = new \$class(%s);\n", $class, implode(', ', $arguments));
} else {
$code = sprintf(" \$instance = new %s(%s);\n", $definition->getClass(), implode(', ', $arguments));
}

if ($definition->isShared()) {
$code .= sprintf(" \$this->shared['$id'] = \$instance;\n");
$code = sprintf("$instantiation = new \\%s(%s);\n", substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments));
}

return $code;
Expand Down Expand Up @@ -180,7 +171,6 @@ protected function get{$name}Service()

$code .=
$this->addServiceInclude($id, $definition).
$this->addServiceShared($id, $definition).
$this->addServiceInstance($id, $definition).
$this->addServiceMethodCalls($id, $definition).
$this->addServiceConfigurator($id, $definition).
Expand Down Expand Up @@ -284,8 +274,6 @@ protected function startClass($class, $baseClass)
*/
class $class extends $baseClass implements TaggedContainerInterface
{
protected \$shared = array();
EOF;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/HttpKernel/Kernel.php
Expand Up @@ -178,7 +178,7 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ
$this->boot();
}

return $this->container->getHttpKernelService()->handle($request, $type, $catch);
return $this->container->get('http_kernel')->handle($request, $type, $catch);
}

/**
Expand Down
Expand Up @@ -99,24 +99,6 @@ public function testGetServiceIds()
$this->assertEquals(array('bar', 'foo_bar', 'foo.baz', 'service_container'), $sc->getServiceIds(), '->getServiceIds() returns defined service ids by getXXXService() methods');
}

/**
* @covers Symfony\Component\DependencyInjection\Container::__call
*/
public function testGetCall()
{
$sc = new Container();
$sc->set('foo_bar.foo', $foo = new \stdClass());
$this->assertEquals($foo, $sc->getFooBar_FooService(), '__call() finds services is the method is getXXXService()');

try {
$sc->getFooBar_Foo();
$this->fail('__call() throws a \BadMethodCallException exception if the method is not a service method');
} catch (\Exception $e) {
$this->assertInstanceOf('\BadMethodCallException', $e, '__call() throws a \BadMethodCallException exception if the method is not a service method');
$this->assertEquals('Call to undefined method Symfony\Component\DependencyInjection\Container::getFooBar_Foo.', $e->getMessage(), '__call() throws a \BadMethodCallException exception if the method is not a service method');
}
}

/**
* @covers Symfony\Component\DependencyInjection\Container::set
*/
Expand All @@ -142,13 +124,6 @@ public function testGet()
$sc->set('bar', $bar = new \stdClass());
$this->assertSame($sc->get('bar'), $bar, '->getServiceIds() prefers to return a service defined with a getXXXService() method than one defined with set()');

try {
$sc->get(new \stdClass());
$this->fail('->get() throws a \InvalidArgumentException exception if the service id is not a string');
} catch (\Exception $e) {
$this->assertInstanceOf('\InvalidArgumentException', $e, '->get() throws a \InvalidArgumentException exception if the service id is not a string');
}

try {
$sc->get('');
$this->fail('->get() throws a \InvalidArgumentException exception if the service is empty');
Expand Down
Expand Up @@ -77,7 +77,6 @@ public function testOverrideServiceWhenUsingADumpedContainer()
$container->set('bar', $bar = new \stdClass());
$container->setParameter('foo_bar', 'foo_bar');

$this->assertEquals($bar, $container->getBarService(), '->set() overrides an already defined service');
$this->assertEquals($bar, $container->get('bar'), '->set() overrides an already defined service');
}

Expand All @@ -90,6 +89,6 @@ public function testOverrideServiceWhenUsingADumpedContainerAndServiceIsUsedFrom
$container = new \ProjectServiceContainer();
$container->set('bar', $bar = new \stdClass());

$this->assertSame($bar, $container->getFooService()->bar, '->set() overrides an already defined service');
$this->assertSame($bar, $container->get('foo')->bar, '->set() overrides an already defined service');
}
}
Expand Up @@ -15,8 +15,6 @@
*/
class Container extends AbstractContainer implements TaggedContainerInterface
{
protected $shared = array();

/**
* Constructor.
*/
Expand Down
Expand Up @@ -15,8 +15,6 @@
*/
class ProjectServiceContainer extends Container implements TaggedContainerInterface
{
protected $shared = array();

/**
* Constructor.
*/
Expand Down
Expand Up @@ -15,8 +15,6 @@
*/
class ProjectServiceContainer extends Container implements TaggedContainerInterface
{
protected $shared = array();

/**
* Constructor.
*/
Expand Down

0 comments on commit 60bbb8f

Please sign in to comment.