Skip to content

Commit 85fe678

Browse files
[DependencyInjection] Avoid unnecessary calls to strtolower()
1 parent 90f88bc commit 85fe678

File tree

2 files changed

+57
-52
lines changed

2 files changed

+57
-52
lines changed

Container.php

Lines changed: 56 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ class Container implements IntrospectableContainerInterface
7676
protected $scopeStacks;
7777
protected $loading = array();
7878

79+
private $underscoreMap = array('_' => '', '.' => '_', '\\' => '_');
80+
7981
/**
8082
* Constructor.
8183
*
@@ -218,7 +220,7 @@ public function set($id, $service, $scope = self::SCOPE_CONTAINER)
218220

219221
$this->services[$id] = $service;
220222

221-
if (method_exists($this, $method = 'synchronize'.strtr($id, array('_' => '', '.' => '_', '\\' => '_')).'Service')) {
223+
if (method_exists($this, $method = 'synchronize'.strtr($id, $this->underscoreMap).'Service')) {
222224
$this->$method();
223225
}
224226

@@ -242,17 +244,20 @@ public function set($id, $service, $scope = self::SCOPE_CONTAINER)
242244
*/
243245
public function has($id)
244246
{
245-
$id = strtolower($id);
246-
247-
if ('service_container' === $id) {
248-
return true;
247+
for ($i = 2;;) {
248+
if ('service_container' === $id
249+
|| isset($this->aliases[$id])
250+
|| isset($this->services[$id])
251+
|| array_key_exists($id, $this->services)
252+
) {
253+
return true;
254+
}
255+
if (--$i && $id !== $lcId = strtolower($id)) {
256+
$id = $lcId;
257+
} else {
258+
return method_exists($this, 'get'.strtr($id, $this->underscoreMap).'Service');
259+
}
249260
}
250-
251-
return isset($this->services[$id])
252-
|| array_key_exists($id, $this->services)
253-
|| isset($this->aliases[$id])
254-
|| method_exists($this, 'get'.strtr($id, array('_' => '', '.' => '_', '\\' => '_')).'Service')
255-
;
256261
}
257262

258263
/**
@@ -280,10 +285,7 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
280285
// available services. Service IDs are case insensitive, however since
281286
// this method can be called thousands of times during a request, avoid
282287
// calling strtolower() unless necessary.
283-
foreach (array(false, true) as $strtolower) {
284-
if ($strtolower) {
285-
$id = strtolower($id);
286-
}
288+
for ($i = 2;;) {
287289
if ('service_container' === $id) {
288290
return $this;
289291
}
@@ -294,57 +296,60 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
294296
if (isset($this->services[$id]) || array_key_exists($id, $this->services)) {
295297
return $this->services[$id];
296298
}
297-
}
298299

299-
if (isset($this->loading[$id])) {
300-
throw new ServiceCircularReferenceException($id, array_keys($this->loading));
301-
}
300+
if (isset($this->loading[$id])) {
301+
throw new ServiceCircularReferenceException($id, array_keys($this->loading));
302+
}
302303

303-
if (isset($this->methodMap[$id])) {
304-
$method = $this->methodMap[$id];
305-
} elseif (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_', '\\' => '_')).'Service')) {
306-
// $method is set to the right value, proceed
307-
} else {
308-
if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {
309-
if (!$id) {
310-
throw new ServiceNotFoundException($id);
311-
}
304+
if (isset($this->methodMap[$id])) {
305+
$method = $this->methodMap[$id];
306+
} elseif (--$i && $id !== $lcId = strtolower($id)) {
307+
$id = $lcId;
308+
continue;
309+
} elseif (method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) {
310+
// $method is set to the right value, proceed
311+
} else {
312+
if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {
313+
if (!$id) {
314+
throw new ServiceNotFoundException($id);
315+
}
312316

313-
$alternatives = array();
314-
foreach ($this->services as $key => $associatedService) {
315-
$lev = levenshtein($id, $key);
316-
if ($lev <= strlen($id) / 3 || false !== strpos($key, $id)) {
317-
$alternatives[] = $key;
317+
$alternatives = array();
318+
foreach ($this->services as $key => $associatedService) {
319+
$lev = levenshtein($id, $key);
320+
if ($lev <= strlen($id) / 3 || false !== strpos($key, $id)) {
321+
$alternatives[] = $key;
322+
}
318323
}
324+
325+
throw new ServiceNotFoundException($id, null, null, $alternatives);
319326
}
320327

321-
throw new ServiceNotFoundException($id, null, null, $alternatives);
328+
return;
322329
}
323330

324-
return;
325-
}
331+
$this->loading[$id] = true;
326332

327-
$this->loading[$id] = true;
333+
try {
334+
$service = $this->$method();
335+
} catch (\Exception $e) {
336+
unset($this->loading[$id]);
328337

329-
try {
330-
$service = $this->$method();
331-
} catch (\Exception $e) {
332-
unset($this->loading[$id]);
338+
if (array_key_exists($id, $this->services)) {
339+
unset($this->services[$id]);
340+
}
333341

334-
if (array_key_exists($id, $this->services)) {
335-
unset($this->services[$id]);
336-
}
342+
if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
343+
return;
344+
}
337345

338-
if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
339-
return;
346+
throw $e;
340347
}
341348

342-
throw $e;
343-
}
344-
345-
unset($this->loading[$id]);
349+
unset($this->loading[$id]);
346350

347-
return $service;
351+
return $service;
352+
}
348353
}
349354

350355
/**

Tests/ContainerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ public function testEnterLeaveCurrentScope()
289289

290290
$container->enterScope('foo');
291291
$scoped2 = $container->get('scoped');
292-
$scoped3 = $container->get('scoped');
292+
$scoped3 = $container->get('SCOPED');
293293
$scopedFoo2 = $container->get('scoped_foo');
294294

295295
$container->leaveScope('foo');

0 commit comments

Comments
 (0)