Browse Source

[DependencyInjection] added a __call() method to Container to allow usage of getXXXService() methods even whithout a PHP dump (allows for faster production environments)

Fabien Potencier 15 năm trước cách đây
mục cha
commit
f8e3b4b035

+ 18 - 0
src/Symfony/Components/DependencyInjection/Container.php

@@ -375,6 +375,24 @@ class Container implements ContainerInterface, \ArrayAccess, \Iterator
     return $this->count > 0;
   }
 
+  /**
+   * Catches unknown methods.
+   *
+   * @param string $method    The called method name
+   * @param array  $arguments The method arguments
+   *
+   * @return mixed
+   */
+  public function __call($method, $arguments)
+  {
+    if (!preg_match('/^get(.+)Service$/', $method, $match))
+    {
+      throw new \RuntimeException(sprintf('Call to undefined method %s::%s.', get_class($this), $method));
+    }
+
+    return $this->getService(self::underscore($match[1]));
+  }
+
   static public function camelize($id)
   {
     return preg_replace(array('/(^|_)+(.)/e', '/\.(.)/e'), array("strtoupper('\\2')", "'_'.strtoupper('\\1')"), $id);

+ 17 - 1
tests/unit/Symfony/Components/DependencyInjection/ContainerTest.php

@@ -14,7 +14,7 @@ use Symfony\Components\DependencyInjection\Container;
 
 $fixturesPath = __DIR__.'/../../../../fixtures/Symfony/Components/DependencyInjection/';
 
-$t = new LimeTest(41);
+$t = new LimeTest(43);
 
 // __construct()
 $t->diag('__construct()');
@@ -206,3 +206,19 @@ $t->is($services, array(
   'foo.baz' => spl_object_hash($sc->__foo_baz),
   'foo' => spl_object_hash($foo)),
 'Container implements the Iterator interface');
+
+// __call()
+$t->diag('__call()');
+$sc = new Container();
+$sc->setService('foo_bar.foo', $foo = new stdClass());
+$t->is($sc->getFooBar_FooService(), $foo, '__call() finds services is the method is getXXXService()');
+
+try
+{
+  $sc->getFooBar_Foo();
+  $t->pass('__call() throws a \RuntimeException exception if the method is not a service method');
+}
+catch (\RuntimeException $e)
+{
+  $t->pass('__call() throws a \RuntimeException exception if the method is not a service method');
+}